力扣101.对称二叉树
对于堆成二叉树,很多人有个误区,以为我们要比较的是一个结点的左右节点,其实不是这样的,我们要比较的是节点的左右子树。
假设我们有如下的一颗二叉树
我们要比较的是左右孩子吗,其实不是,我们需要比较这颗树的内侧和外侧
当左侧为空,右侧不为空时 不对称
当左侧不为空,右侧为空时 不对称
当左侧不为空右侧不为空,但值不相等时 不对称
只有当左侧等于右侧时,才对称。
这个时候我们就可以递归遍历的代码了
递归遍历三要素
- 确定递归参数及返回
因为我们需要知道这颗树是否对称,所以返回值为boolean类型。当然参数就是这颗树了
- 确定终止条件
终止条件就是前面讲的什么时候返回false,什么时候返回true
- 确定递归逻辑
递归逻辑就是
- 比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
- 比较内测是否对称,传入左节点的右孩子,右节点的左孩子。
- 如果左右都对称就返回true ,有一侧不对称就返回false 。
结合这些,我们能够写出代码
public boolean isSymmetric1(TreeNode root) {
return compare(root.left, root.right);
}
private 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 compareOutside = compare(left.left, right.right);
// 比较内侧
boolean compareInside = compare(left.right, right.left);
return compareOutside && compareInside;
}
这是用递归法做的,还有迭代法,如果不知道如何使用迭代法遍历二叉树,可以去看我前面的文章,每日算法之二叉树的非递归遍历_weixin_57597001的博客-CSDN博客里面详细写了如何用迭代法遍历二叉树
这里也给出迭代的代码
public boolean isSymmetric2(TreeNode root) {
Deque<TreeNode> deque = new LinkedList<>();
deque.offerFirst(root.left);
deque.offerLast(root.right);
while (!deque.isEmpty()) {
TreeNode leftNode = deque.pollFirst();
TreeNode rightNode = deque.pollLast();
if (leftNode == null && rightNode == null) {
continue;
}
// 以上三个判断条件合并
if (leftNode == null || rightNode == null || leftNode.val != rightNode.val) {
return false;
}
deque.offerFirst(leftNode.left);
deque.offerFirst(leftNode.right);
deque.offerLast(rightNode.right);
deque.offerLast(rightNode.left);
}
return true;
}