leetcode cs-notes-树(一)【js】
Maximum Depth of Binary Tree (Easy)
【递归】
var maxDepth = function(root) {
if(root === null) return 0;
const max = (a, b) => {
return a > b ? a : b;
}
return max(maxDepth(root.left), maxDepth(root.right)) + 1;
};
【层序遍历】
广度优先
var maxDepth = function(root) {
const queue = [];
let ans = 0;
if(!root) return ans;
queue.push(root);
while(queue.length > 0){
let curSize = queue.length;
while(curSize > 0){
let curNode = queue.shift();
if(curNode.left) queue.push(curNode.left);
if(curNode.right) queue.push(curNode.right);
curSize --;
}
ans ++;
}
return ans;
};
Balanced Binary Tree (Easy)
【自顶向下】
就是计算左右子树的高度,如果高度差大于1,就不是平衡树。
var isBalanced = function(root) {
const maxDepth = (node) => {
if(!node) return 0;
let l = maxDepth(node.left);
let r = maxDepth(node.right);
return Math.max(l, r) + 1;
}
return !(maxDepth(root.left) - maxDepth(root.right)) > 1 && isBalanced(root.left) && isBalanced(root.right);
}
上面这个复杂度以看就很高,很多多余计算。maxDepth
的复杂度是O(h),最坏情况需要遍历所有节点O(n),对于某一个节点,它需要调用自己的高度次数的maxDepth
,所以复杂度是O(nlogn)。
【自底向上】
跟上面的比起来,这个不用对每一个节点都判断是否平衡,遇到不平衡时res = false
,只对根节点执行maxDepth
,复杂度下降到最差情况是O(n),就算每个节点都计算一次maxDepth
。
var isBalanced = function(root) {
let res = true;
const maxDepth = (node) => {
if(!node) return 0;
let l = maxDepth(node.left);
let r = maxDepth(node.right);
if(Math.abs(l - r) > 1) res = false;
return Math.max(l, r) + 1;
}
maxDepth(root);
return res;
}
一路递归到叶节点,再返回,一路上只要有非平衡树,直接一路返回false。
var isBalanced = function(root) {
const maxDepth = (node) => {
if(!node) return 0;
let l = 0;
let r = 0;
l = maxDepth(node.left);
r = maxDepth(node.right);
if(l === -1 || r === -1 || Math.abs(l-r) > 1)
return -1;
else
return Math.max(l, r) + 1;
}
return maxDepth(root) >= 0;
};
Diameter of Binary Tree (Easy)
如图我们可以知道路径 [9, 4, 2, 5, 7, 8] 可以被看作以 22 为起点,从其左儿子向下遍历的路径 [2, 4, 9] 和从其右儿子向下遍历的路径 [2, 5, 7, 8] 拼接得到。
假设我们知道对于该节点的左儿子向下遍历经过最多的节点数 LL (即以左儿子为根的子树的深度) 和其右儿子向下遍历经过最多的节点数 RR (即以右儿子为根的子树的深度),那么以该节点为起点的路径经过节点数的最大值即为 L+R+1,路径长度即为 L+R。
var diameterOfBinaryTree = function(root) {
let ans = 0;
const maxDepth = (node) => {
if(!node) return 0;
let l = maxDepth(node.left);
let r = maxDepth(node.right);
ans = (l+r) > ans ? l+r : ans;
return Math.max(l, r) + 1;
}
maxDepth(root);
return ans;
};
Invert Binary Tree (Easy)
【递归】
感觉思路就算从考虑node开始,只要把node处理好,它的左子树右子树也会被处理好。就需要达到这样的一个解决状态。
复杂度O(n),因为每个节点都执行一次invertTreeNode
var invertTree = function(root) {
const invertTreeNode = (node) => {
if(node === null) return null;
let tmpNode = node.left;
node.left = invertTreeNode(node.right);
node.right = invertTreeNode(tmpNode);
return node;
}
return invertTreeNode(root);
};
Merge Two Binary Trees (Easy)
哎写起感觉是一种思路
复杂度O(n),也是每个节点都执行一次mergeTreesNode
var mergeTrees = function(t1, t2) {
const mergeTreesNode = (node1, node2) => {
if(node1 === null && node2 !== null)
return node2;
if(node1 !== null && node2 === null)
return node1;
if(!(node1 && node2)) return null;
let node = new TreeNode();
node.val = node1.val + node2.val;
node.left = mergeTreesNode(node1.left, node2.left);
node.right = mergeTreesNode(node1.right, node2.right);
return node;
}
return mergeTreesNode(t1, t2);
};