「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」
对称二叉树
给定一个二叉树,检查它是否是镜像对称的。
例如,二叉树 [1,2,2,3,4,4,3] 是对称的
但是下面这个
[1,2,2,null,3,null,3] 则不是镜像对称的:
小亦呀漏洞百出的糊涂做法
在做完这道对称二叉树之前,我刚做完翻转二叉树的力扣题,然后我不聪明的小脑瓜一想,对称二叉树翻转过来,相应位置的值也是一样,那我拿着一个tempRoot存储原本那个root,然后把root翻转过来,再把tempRoot和reverseRoot一比较不就行了吗,然后写出了下列的傻瓜代码
var isSymmetric = function(root) {
const dfs = function (root) {
if (root=== null) {
return ;
}
temp = root.left;
root.left = root.right;
root.right = temp;
dfs(root.left);
dfs(root.right);
}
let tempRoot = root;
dfs(root);
let reverseRoot = root;
return tempRoot === reverseRoot;
};
然后一提交,果然有问题,debug之后,我就明白,我写了什么憨批代码,忽略了很多JS基础知识,首先let tempRoot = root,let tempRoot = root,我脑子一热想的是tempRoot和reverseRoot存储翻转前和翻转后的root对象副本,但在JS里,这代码是对root对象的引用,存储的是root的地址,也就是只要root地址不变,无论root咋变化,tempRoot存储的地址还是指向变化后的root,tempRoot和reverseRoot存储的地址是一样的,那么tempRoot === reverseRoot,一定是true。第二个很不好的点,是我简简单单的对象比较,我原意是比较两个对象相应位置的值是一样的,但直接tempRoot === reverseRoot是完全不对的。
正确的递归做法
首先想清楚,判断对称二叉树要比较的是哪两个节点,要比较的不是左右节点!
对于二叉树是否对称,要比较的是根节点的左子树与右子树是不是相互翻转的,理解这一点就知道了其实我们要比较的是两个树(这两个树是根节点的左右子树) ,所以在递归遍历的过程中,也是要同时遍历两棵树。
那么如果比较,比较的是两个子树的里侧和外侧的元素是否相等
var isSymmetric = function(root) {
//使用递归遍历左右子树 递归三部曲
// 1. 确定递归的参数 root.left root.right和返回值true false
const compareNode=function(left,right){
//2. 确定终止条件 空的情况
if(left===null&&right!==null||left!==null&&right===null){
return false;
}else if(left===null&&right===null){
return true;
}else if(left.val!==right.val){
return false;
}
//3. 确定单层递归逻辑
let outSide=compareNode(left.left,right.right);
let inSide=compareNode(left.right,right.left);
return outSide&&inSide;
}
if(root===null){
return true;
}
return compareNode(root.left,root.right);
};