一、589. N 叉树的前序遍历 - 力扣(LeetCode)
1.1题目
给定一个 n 叉树的根节点 root
,返回 其节点值的 前序遍历 。
n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null
分隔(请参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6] 输出:[1,3,5,6,2,4]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14] 输出:[1,2,3,6,7,11,14,4,8,12,5,9,13,10]
1.2思路分析
方法一递归
方法二迭代
1.3代码实现
方法一递归
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
// 递归遍历
class Solution {
public List<Integer> preorder(Node root) {
List<Integer> res = new ArrayList<>();
pre(root,res);
return res;
}
public void pre (Node root ,List<Integer> res){
if(root == null) return;
// 将根节点的值放入到数组中
res.add(root.val);
// 循环遍历孩子
for(Node ch : root.children){
pre(ch,res);
}
}
}
方法二迭代
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<Integer> preorder(Node root) {
if(root == null) return Collections.emptyList();
// 先将根节点放置到栈中;然后依次遍历根节点的所有孩子
Stack<Node> stack = new Stack<>();
List<Integer> res = new ArrayList<>();
stack.push(root);
while(!stack.isEmpty()){
// 弹出根节点
// 并将根节点的值添加到结果数组中
Node temp = stack.pop();
res.add(temp.val);
// 获得该根节点的所有孩子节点并放入到数组中
List<Node> children = temp.children;
// 将孩子节点依次遍历到栈中 因为入栈顺序是由右向左所以i从children.size()-1开始遍历
for(int i = children.size()-1 ; i>=0 ;i--){
// 依次遍历孩子节点
stack.push(children.get(i));
}
}
return res;
}
}
二、590. N 叉树的后序遍历 - 力扣(LeetCode)
2.1题目
给定一个 n 叉树的根节点 root
,返回 其节点值的 后序遍历 。
n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null
分隔(请参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6] 输出:[5,6,3,2,4,1]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14] 输出:[2,6,14,11,7,3,12,8,4,13,9,10,5,1]
提示:
- 节点总数在范围
[0, 104]
内 0 <= Node.val <= 104
- n 叉树的高度小于或等于
1000
2.2思路分析
方法一递归
方法二迭代
2.3代码实现
方法一递归
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<Integer> postorder(Node root) {
List<Integer> res = new ArrayList<>();
pre(root,res);
return res;
}
public void pre(Node node,List<Integer> res){
if(node == null) return;
for(Node ch : node.children){
pre(ch,res);
}
// 先便孩子,最终使得每个孩子成为根节点,然后再将根节点添加到结果数组中
res.add(node.val);
}
}
方法二迭代
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
public List<Integer> postorder(Node root) {
if(root == null) return Collections.emptyList();
// 定义栈存放遍历的节点
Stack<Node> stack = new Stack<>();
List<Integer> res = new ArrayList<>();
stack.push(root);
while(!stack.isEmpty()){
Node temp = stack.pop();
res.add(temp.val);
List<Node> children = temp.children;
// 从左向右遍历
for(int i = 0 ;i<children.size(); i++){
stack.push(children.get(i));
}
}
Collections.reverse(res);
return res;
}
}
三、102. 二叉树的层序遍历 - 力扣(LeetCode)
3.1题目
给你二叉树的根节点 root
,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:[[3],[9,20],[15,7]]
示例 2:
输入:root = [1] 输出:[[1]]
示例 3:
输入:root = [] 输出:[]
3.2思路分析
利用队列先入先出的特性存放每层的节点并依次遍历,先根,然后存放根的左孩子与右孩子,依次类推。
3.3代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
// 定义一个结果数组
List<List<Integer>> resultList = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(TreeNode root) {
if(root == null) return resultList;
fun(root,0);
return resultList;
}
public void fun(TreeNode root ,int deep){
// 定义一个队列存放节点
Queue <TreeNode> queue = new LinkedList<>();
// 定义个临时节点存放结果
TreeNode temp;
// 将根节点放入到队列中
queue.offer(root);
while(!queue.isEmpty()){
// 定义放在循环里面保证每次生成一个新的结果数组
List <Integer> result = new ArrayList<>();
// 每层循环遍历完更新deep
deep = queue.size();
// 将每层的节点依次放入到结果队列中
while(deep >0 ){
temp = queue.poll();
result.add(temp.val);
// 将左孩子与右孩子依次放入到队列中
if(temp.left != null) queue.offer(temp.left);
if(temp.right != null) queue.offer(temp.right);
deep--;
}
resultList.add(result);
}
}
}
四、107. 二叉树的层序遍历 II - 力扣(LeetCode)
4.1题目
给你二叉树的根节点 root
,返回其节点值 自底向上的层序遍历 。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:[[15,7],[9,20],[3]]
示例 2:
输入:root = [1] 输出:[[1]]
示例 3:
输入:root = [] 输出:[]
4.2思路分析
先层序遍历再反转
4.3代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
// 先层序遍历再反转
class Solution {
// 定义一个结果数组放置结果
List<List<Integer>> resultList = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrderBottom(TreeNode root) {
if(root == null) return resultList;
fun(root,0);
// Collections.reverse()没有返回值
Collections.reverse(resultList);
return resultList;
}
public void fun(TreeNode node, int deep){
//定义队列放置结果
Queue <TreeNode> queue = new LinkedList<>();
TreeNode temp;
queue.offer(node);
while(!queue.isEmpty()){
deep = queue.size();
List<Integer> result = new ArrayList<>();
while(deep>0){
temp = queue.poll();
result.add(temp.val);
if(temp.left != null ) queue.offer(temp.left);
if(temp.right!=null) queue.offer(temp.right);
deep--;
}
resultList.add(result);
}
}
}
五、429. N 叉树的层序遍历 - 力扣(LeetCode)
5.1题目
给定一个 N 叉树,返回其节点值的层序遍历。(即从左到右,逐层遍历)。
树的序列化输入是用层序遍历,每组子节点都由 null 值分隔(参见示例)。
示例 1:
输入:root = [1,null,3,2,4,null,5,6] 输出:[[1],[3,2,4],[5,6]]
示例 2:
输入:root = [1,null,2,3,4,5,null,null,6,7,null,8,null,9,10,null,null,11,null,12,null,13,null,null,14] 输出:[[1],[2,3,4,5],[6,7,8,9,10],[11,12,13],[14]]
5.2思路分析
定义队列对n叉树进行依次遍历,根据队列的大小控制队列每层需要出的根节点数量,弹出后,再将根节点的所有孩子加入到队列中,并跟新队列的大小。
5.3代码实现
/*
// Definition for a Node.
class Node {
public int val;
public List<Node> children;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, List<Node> _children) {
val = _val;
children = _children;
}
};
*/
class Solution {
List<List<Integer>> result = new ArrayList<List<Integer>>();
public List<List<Integer>> levelOrder(Node root) {
if(root == null) return result;
fun(root,0);
return result;
}
public void fun(Node root, int deep){
Queue <Node> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
List<Integer> res = new ArrayList<>();
deep = queue.size();
while(deep>0){
Node temp = queue.poll();
res.add(temp.val);
List<Node> children =temp.children;
for(Node ch:children){
queue.offer(ch);
}
deep--;
}
result.add(res);
}
}
}
六、199. 二叉树的右视图 - 力扣(LeetCode)
6.1题目
给定一个二叉树的 根节点 root
,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值。
示例 1:
输入: [1,2,3,null,5,null,4] 输出: [1,3,4]
示例 2:
输入: [1,null,3] 输出: [1,3]
示例 3:
输入: [] 输出: []
6.2思路分析
二叉树的右视图其实就是当前层的最后一个节点的值
6.3代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<Integer> result = new ArrayList<>();
public List<Integer> rightSideView(TreeNode root) {
if (root == null) return result;
fun(root,0);
return result;
}
public void fun(TreeNode root,int deep){
Queue <TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
deep = queue.size();
for(int i = 0; i<deep;i++){
TreeNode temp = queue.poll();
if(temp.left!=null) queue.offer(temp.left);
if(temp.right!= null) queue.offer(temp.right);
// 右视图的结果其实就是当前层的最后一个节点
if(i == deep - 1) result.add(temp.val);
}
}
}
}
七、637. 二叉树的层平均值 - 力扣(LeetCode)
7.1题目
给定一个非空二叉树的根节点 root
, 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5
以内的答案可以被接受。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:[3.00000,14.50000,11.00000] 解释:第 0 层的平均值为 3,第 1 层的平均值为 14.5,第 2 层的平均值为 11 。 因此返回 [3, 14.5, 11] 。
示例 2:
输入:root = [3,9,20,15,7] 输出:[3.00000,14.50000,11.00000]
7.2思路分析
对每层的节点求和取平均。
7.3代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<Double> res = new ArrayList<>();
public List<Double> averageOfLevels(TreeNode root) {
fun(root,0);
return res;
}
public void fun(TreeNode root,int deep){
if(root == null) return ;
Queue<TreeNode> queue = new LinkedList<>();
TreeNode temp;
queue.offer(root);
while(!queue.isEmpty()){
Double sum = 0D ;
deep = queue.size();
int cur = deep;
while(deep>0){
temp = queue.poll();
sum += temp.val;
if(temp.left!=null) queue.offer(temp.left);
if(temp.right!=null) queue.offer(temp.right);
deep--;
}
res.add(sum/cur);
}
}
}
八、515. 在每个树行中找最大值 - 力扣(LeetCode)
8.1题目
给定一棵二叉树的根节点 root
,请找出该二叉树中每一层的最大值。
示例1:
输入: root = [1,3,2,5,3,null,9] 输出: [1,3,9]
示例2:
输入: root = [1,2,3] 输出: [1,3]
8.2思路分析
初始化最大值时需要考虑负数情况,因此需要将其初始化为最小的整数
8.3代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<Integer> result = new ArrayList<>();
public List<Integer> largestValues(TreeNode root) {
fun(root,0);
return result;
}
public void fun(TreeNode node ,int deep){
if(node == null) return;
Queue <TreeNode> queue = new LinkedList<>();
queue.offer(node);
while(!queue.isEmpty()){
deep = queue.size();
int maxTemp = Integer.MIN_VALUE;
while(deep>0){
TreeNode temp = queue.poll();
maxTemp = temp.val > maxTemp ? temp.val:maxTemp;
if(temp.left != null) queue.offer(temp.left);
if(temp.right != null) queue.offer(temp.right);
deep--;
}
result.add(maxTemp);
}
}
}
九、116. 填充每个节点的下一个右侧节点指针 - 力扣(LeetCode)
9.1题目
给定一个 完美二叉树 ,其所有叶子节点都在同一层,每个父节点都有两个子节点。二叉树定义如下:
struct Node { int val; Node *left; Node *right; Node *next; }
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
示例 1:
输入:root = [1,2,3,4,5,6,7] 输出:[1,#,2,3,#,4,5,6,7,#] 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化的输出按层序遍历排列,同一层节点由 next 指针连接,'#' 标志着每一层的结束。
示例 2:
输入:root = [] 输出:[]
9.2思路分析
每个node左子树的next就是node的右子树,每个node右子树的next就是node.next的左子树
9.3代码实现
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
class Solution {
public Node connect(Node root) {
dfs(root, null);
return root;
}
public void dfs(Node node ,Node next){
if(node != null){
node.next = next;
dfs(node.left,node.right);
dfs(node.right, node.next != null ? node.next.left : null );
}
}
}
十、117. 填充每个节点的下一个右侧节点指针 II - 力扣(LeetCode)
10.1题目
给定一个二叉树:
struct Node { int val; Node *left; Node *right; Node *next; }
填充它的每个 next 指针,让这个指针指向其下一个右侧节点。如果找不到下一个右侧节点,则将 next 指针设置为 NULL
。
初始状态下,所有 next 指针都被设置为 NULL
。
示例 1:
输入:root = [1,2,3,4,5,null,7] 输出:[1,#,2,3,#,4,5,7,#] 解释:给定二叉树如图 A 所示,你的函数应该填充它的每个 next 指针,以指向其下一个右侧节点,如图 B 所示。序列化输出按层序遍历顺序(由 next 指针连接),'#' 表示每层的末尾。
示例 2:
输入:root = [] 输出:[]
10.2思路分析
先进行层次遍历,然后将每层的头节点连起来,每层的末尾节点使其指向空
10.3代码实现
/*
// Definition for a Node.
class Node {
public int val;
public Node left;
public Node right;
public Node next;
public Node() {}
public Node(int _val) {
val = _val;
}
public Node(int _val, Node _left, Node _right, Node _next) {
val = _val;
left = _left;
right = _right;
next = _next;
}
};
*/
// 层序遍历,并将每次的头节点用链表连接起来
class Solution {
public Node connect(Node root) {
// 定义一个节点放置头指针
Node ans = root;
if(root == null) return ans;
Queue <Node> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
while(size-->0){
Node temp = queue.poll();
// 当size为0时temp.next指向空指针
if(size!=0)temp.next = queue.peek();
if(temp.left!=null) queue.offer(temp.left);
if(temp.right != null) queue.offer(temp.right);
// size--;
}
}
return ans;
}
}
十一、104. 二叉树的最大深度 - 力扣(LeetCode)
11.1题目
给定一个二叉树 root
,返回其最大深度。
二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:3
示例 2:
输入:root = [1,null,2] 输出:2
11.2思路分析
定义一个变量用来统计层深
11.3代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
int deep = 0;
if(root == null) return deep;
Queue <TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
while(size>0){
TreeNode temp = queue.poll();
if(temp.left!=null) queue.offer(temp.left);
if(temp.right!=null) queue.offer(temp.right);
size--;
}
deep++;
}
return deep;
}
}
十二、111. 二叉树的最小深度 - 力扣(LeetCode)
12.1题目
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明:叶子节点是指没有子节点的节点。
示例 1:
输入:root = [3,9,20,null,null,15,7] 输出:2
示例 2:
输入:root = [2,null,3,null,4,null,5,null,6] 输出:5
12.2思路分析
当左节点与右节点同时为空时,此时为最短的路径
12.3代码实现
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
int deep = 1;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
while(size>0){
TreeNode temp = queue.poll();
if(temp == null) return 0;
if(temp.left == null && temp.right == null){
return deep;
}
if(temp.left!=null) queue.offer(temp.left);
if(temp.right!= null) queue.offer(temp.right);
size--;
}
deep++;
}
return deep;
}
}
十三、226. 翻转二叉树 - 力扣(LeetCode)
13.1题目
给你一棵二叉树的根节点 root
,翻转这棵二叉树,并返回其根节点。
示例 1:
输入:root = [4,2,7,1,3,6,9] 输出:[4,7,2,9,6,3,1]
示例 2:
输入:root = [2,1,3] 输出:[2,3,1]
示例 3:
输入:root = [] 输出:[]
13.2思路分析
方法一递归
方法二迭代
13.3代码实现
方法一递归
前序
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
// 采用前序遍历
// 交换左右孩子
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
// 对坐孩子进行遍历
invertTree(root.left);
invertTree(root.right);
return root;
}
}
后序
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
// 采用后序遍历
// 先对孩子进行遍历
invertTree(root.left);
invertTree(root.right);
// 交换左右孩子
TreeNode temp = root.left;
root.left = root.right;
root.right = temp;
return root;
}
}
方法二迭代
前序
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
int size = stack.size();
TreeNode temp = stack.pop();
TreeNode temp1 = temp.left;
temp.left = temp.right;
temp.right = temp1;
if(temp.right != null) stack.push(temp.right);
if(temp.left!= null) stack.push(temp.left);
}
return root;
}
}
后续
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while(!stack.isEmpty()){
int size = stack.size();
TreeNode temp = stack.pop();
if(temp.right != null) stack.push(temp.right);
if(temp.left!= null) stack.push(temp.left);
TreeNode temp1 = temp.left;
temp.left = temp.right;
temp.right = temp1;
}
return root;
}
}
层序
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
Queue<TreeNode> queue = new LinkedList<>();
TreeNode node,temp;
queue.offer(root);
while(!queue.isEmpty()){
int size = queue.size();
while(size>0){
temp = queue.poll();
// 交换节点的左右子节点
node = temp.left;
temp.left = temp.right;
temp.right = node;
if(temp.left!= null) queue.offer(temp.left);
if(temp.right!=null) queue.offer(temp.right);
size--;
}
}
return root;
}
}
十四、101. 对称二叉树 - 力扣(LeetCode)
14.1题目
给你一个二叉树的根节点 root
, 检查它是否轴对称。
示例 1:
输入:root = [1,2,2,3,4,4,3] 输出:true
示例 2:
输入:root = [1,2,2,null,3,null,3] 输出:false
14.2思路分析
方法一递归
方法二迭代
首先要比较的顺序,有叶子节点向根节点比较,同时叶子节点再比较时,应该分为外侧的两个节点进行比较与内侧两个节点比较,如果两次比较的结果完全相同才是完全相同的。
比较的几个规则:
左侧不为空且右侧为空时,不对称;
左侧为空且右侧不为空时,不对称;
左侧和右侧都为空时,需要进一步判断下一个节点;
左侧右侧都不为空,且左侧的值与右侧的值不相等时,不对称。
14.4代码实现
方法一递归
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
return compare(root.left,root.right);
}
public boolean compare(TreeNode left,TreeNode right){
if(left == null && right != null) return false;
if(left != null && right == null) return false;
if(left == null && right == null) return true;
if(left.val != right.val) return false;
boolean outside = compare(left.left,right.right);
boolean inseide = compare(left.right,right.left);
return outside && inseide;
}
}
方法二迭代
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {
Stack<TreeNode> stack= new Stack<>();
// 将左节点与右节点分辨传入到栈中
stack.push(root.left);
stack.push(root.right);
while(!stack.isEmpty()){
TreeNode right = stack.pop();
TreeNode left = stack.pop();
if(right != null && left == null) return false;
if(right == null && left != null) return false;
if(right == null && left == null) continue;
if(right.val != left.val) return false;
// 因为栈是先入后出
// 所以先比较将内侧放入栈中,这样再比较时就是先比较外侧
stack.push(left.right);
stack.push(right.left);
// 进一步比较外侧
stack.push(left.left);
stack.push(right.right);
}
return true;
}
}