剑指 Offer 28. 对称的二叉树
请实现一个函数,用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样,那么它是对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的。
1
/ \
2 2
/ \ / \
3 4 4 3
但是下面这个 [1,2,2,null,3,null,3] 则不是镜像对称的:
1
/ \
2 2
\ \
3 3
解题思路:
头节点直接判断两个子节点值是否相等,不想等就代表不对称
对于头节点的左右子节点比较的是两个子树的内侧和外侧的元素是否相等。如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/e08de727b9676df7ce6056fc60583a2d.png)
实现逻辑:
特殊值处理:当传入的头节点为空,直接返回true,因为空树就是对称的。
递归法:(递归三部曲)
确定递归函数的参数和返回值
因为我们要比较的是根节点的两个子树是否是相互翻转的,进而判断这个树是不是对称树,所以要比较的是两个树,参数自然也是左子树节点和右子树节点。返回值自然是boolean类型。
booleancheckFun(TreeNoderootA, TreeNoderootB);
确定终止条件
传入的两个节点都为空,返回true,其中一个节点为空或者两个节点都不是空但是两个节点值不相等,返回true。
if(rootA==null&&rootB==null) returntrue;
if(rootB==null||rootA==null||rootA.val!=rootB.val) returnfalse;
确定单层递归的逻辑
此时才进入单层递归的逻辑,单层递归的逻辑就是处理 左右节点都不为空,且数值相同的情况。
比较二叉树外侧是否对称:传入的是左节点的左孩子,右节点的右孩子。
比较内测是否对称,传入左节点的右孩子,右节点的左孩子。
如果左右都对称就返回true ,有一侧不对称就返回false 。
returncheckFun(rootA.left, rootB.right) &&checkFun(rootA.right, rootB.left);
基于上面递归三部曲,代码就写完了。
classSolution {
publicbooleanisSymmetric(TreeNoderoot) {
if(root==null) returntrue;
returncheckFun(root.left, root.right);
}
publicbooleancheckFun(TreeNoderootA, TreeNoderootB){
if(rootA==null&&rootB==null) returntrue;
if(rootB==null||rootA==null||rootA.val!=rootB.val) returnfalse;
returncheckFun(rootA.left, rootB.right) &&checkFun(rootA.right, rootB.left);
}
}
实现逻辑图:
![](https://i-blog.csdnimg.cn/blog_migrate/9dc21f3141898093200edbc0344d4773.png)