左右节点递归,有节点就+1;
- DFS 自下向上的递归
var maxDepth = function(root) {
if(root==null)return 0;
let maxleft = maxDepth(root.left);
let maxright=maxDepth(root.right);
return Math.max(maxleft,maxright)+1;
};
递归三部:
1.确定递归函数的参数和返回值;
2.确定终止条件;
3.确定单层递归的逻辑。
树的遍历找深度
递归三部曲!
var invertTree = function(root) {
if(root==null)return null;
const p = root.left;
root.left=invertTree(root.right);
root.right=invertTree(p);
return root;
};
var mergeTrees = function(root1, root2) {
if(root1==null) return root2;
if(root2==null) return root1;
root1.val += root2.val;
root1.left = mergeTrees(root1.left,root2.left);
root1.right = mergeTrees(root1.right,root2.right);
return root1;
};
搜索树 分而治之。
数组中值下标,Math.floor(left+(right-left)/2),left和right指下标,例0,len-1;
终止条件!!!!
新建节点 let root = new TreeNode(nums[mid]);
var sortedArrayToBST = function(nums) {
if(nums.length==0)return null;
let mid = Math.floor(nums.length/2);
let root = new TreeNode(nums[mid]);
root.left = sortedArrayToBST(nums.slice(0,mid));
root.right = sortedArrayToBST(nums.slice(mid+1));
return root;
};
var isSameTree = function(p, q) {
if(p==null&&q==null)return true;
if(q&&p&&p.val==q.val){
return isSameTree(p.left,q.left)&&isSameTree(p.right,q.right);
}
else{
return false;
}
};
每层的返回逻辑
var trimBST = function(root, low, high) {
if(root==null) return null;
if(root.val>high){return trimBST(root.left,low,high);}
if(root.val<low){return trimBST(root.right,low,high);}
root.left = trimBST(root.left,low,high);
root.right = trimBST(root.right,low,high);
return root;
};
没写出来,要再构造一个函数。
求深度适合用前序遍历,而求高度适合用后序遍历。
用递归三部曲 + 后序遍历 左右中 当前左子树右子树高度相差大于1就返回-1
var isBalanced = function(root) {
const deepth=function(r){
if(r==null) {return 0};
let dl= deepth(r.left);
if(dl==-1){return -1;}
let dr = deepth(r.right);
if(dr==-1){return -1;}
if(Math.abs(dl-dr)>1){return -1;}
else{return Math.max(dl,dr)+1;}
}
return deepth(root)==-1?false:true;
};
1、确定参数和返回值;
返回值要返回传入节点为根节点树的深度。
那么如何标记左右子树是否差值大于1呢?两个矛盾了没想出来
如果当前传入节点为根节点的二叉树已经不是二叉平衡树了,还返回高度的话就没有意义了。
所以如果已经不是二叉平衡树了,可以返回-1 来标记已经不符合平衡树的规则了。
没想出来,外层对称,内层对称
如果新建函数,那原函数一定会引用新函数。
新建的函数放里面放外面都行。
var isSymmetric = function(root) {
if(root==null)return true;
//确定递归的参数 root.left root.right和返回值true false
const campare = function(r,l){
//终止条件
if(r==null&&l==null) return true;
else if(r==null)return false;
else if(l==null)return false;
else if(r.val != l.val)return false;
//单层逻辑
let outside = campare(l.left,r.right);
let inside =campare(l.right,r.left);
return outside&&inside;
}
return campare(root.right,root.left);
};
迭代法,使用对列,也可以使用栈,
var isSymmetric = function(root) {
if(root==null)return true;
let que =[];
que.push(root.left);
que.push(root.right);
while(que.length){
let leftNode = que.shift();
let rightNode= que.shift();
if(leftNode==null&&rightNode==null)continue;
else if(leftNode==null||rightNode==null||leftNode.val!=rightNode.val)return false;
que.push(leftNode.left);
que.push(rightNode.right);
que.push(leftNode.right);
que.push(rightNode.left);
}
return true;
};
自己写的看起来,代码看起来不简洁。
var lowestCommonAncestor = function(root, p, q) {
const findRoot=function(r,v,f){
f.push(r);
if(v.val>r.val){return findRoot(r.right,v,f);}
if(v.val<r.val){return findRoot(r.left,v,f);}
if(v.val==r.val){return f;}
}
let fp=[];
let fq=[];
let pf = findRoot(root,p,fp);
let qf = findRoot(root,q,fq);
let res =0;
while(pf.length||qf.length){
let vp = pf.length?pf.shift():0;
let vq = qf.length?qf.shift():0;
if(vp==vq){res =vp;}
if(vp!=vq) {break;}
}
return res;
};
是因为解题思路复杂了。
应该比较p,q和当前root的大小,p,q在当前root两侧时,就是最近节点。
迭代法
var lowestCommonAncestor = function(root, p, q) {
while(root){
if((p.val<=root.val&&q.val>=root.val)||(q.val<=root.val&&p.val>=root.val))return root;
else if(p.val<=root.val&&q.val<=root.val) {root = root.left;}
else if(p.val>=root.val&&q.val>=root.val) {root = root.right;}
}
};