题目链接
题目描述
注意
- 最终返回的是布尔值,判断该二叉树是否是对称二叉树
- 对称二叉树要求该二叉树是镜像对称的
解答思路
- 采用递归的思想,对两侧节点从边缘向中间进行遍历判断,直到有节点不对称(直接返回false)或遍历完为止
- 对两个节点进行比较是否对称时,如果两个节点都是null,则直接返回true,如果其中只有一个为null,则直接返回false,否则还需要比较两节点的值是否相同以及左侧节点的左子树和右侧节点的右子树是否相同以及左侧节点的右子树和右侧节点的左子树是否相同才能确定
- 另一种思路是迭代,采用两个队列分别存储左侧的节点和右侧节点,分别从左右边界向中间遍历每一层的节点是否对称,如果不对称则直接返回false,否则将下一层节点添加到队列中(注意判断节点为null的情况)
代码
方法一:
// 递归
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true;
}
return check(root.left, root.right);
}
public boolean check(TreeNode p, TreeNode q) {
if (p == null && q == null) {
return true;
}
if (p == null || q == null) {
return false;
}
if (p.val != q.val) {
return false;
}
return check(p.left, q.right) && check(p.right, q.left);
}
}
方法二:
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true;
}
if (root.left == null && root.right == null) {
return true;
}
if (root.left == null ^ root.right == null) {
return false;
}
Deque<TreeNode> dq1 = new ArrayDeque<>();
Deque<TreeNode> dq2 = new ArrayDeque<>();
dq1.offer(root.left);
dq2.offer(root.right);
while (!dq1.isEmpty() && !dq2.isEmpty()) {
// 每一层dq1和dq2的元素应该相同,否则之前就已经返回false
int size = dq1.size();
for (int i = 0; i < size; i++) {
TreeNode p = dq1.poll();
TreeNode q = dq2.poll();
if (p.val != q.val) {
return false;
}
if (p.left == null ^ q.right == null) {
return false;
}
if (p.left != null && q.right != null) {
dq1.offer(p.left);
dq2.offer(q.right);
}
if (p.right == null ^ q.left == null) {
return false;
}
if (p.right != null && q.left != null) {
dq1.offer(p.right);
dq2.offer(q.left);
}
}
}
return true;
}
}
关键点
- 采用双指针分别对二叉树的左右两侧进行遍历,初始都从root出发,遍历左侧节点的指针先遍历左子树,再遍历右子树;而遍历右侧节点的指针先遍历右子树,再遍历左子树
- 采用递归的思想,如果两个节点都不为null,只要同时满足两个节点的值相等并且检查其左右子树也对称才返回true,否则其下有一处不对称都会返回false
- 迭代的思想