1.二叉树的最大深度
题目:
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
说明: 叶子节点是指没有子节点的节点。
思路:要得到深度,就要遍历树,高度是一层一层累加的,所以采用递归的办法,逐级的获取高度,如果存在左节点或者右节点则自增1,然后计算下一个节点的深度。
var maxDepth = function(root) {
if (!root) return 0;
const a = (root, length) => {
if (!root.left && !root.right) {
return length;
} else if (!root.left) {
return a(root.right, length + 1);
} else if (!root.right) {
return a(root.left, length + 1);
} else {
return Math.max(a(root.right, length + 1), a(root.left, length + 1));
}
};
return a(root, 1);
};
问题:判断太多,因为已经判断了当前节点为null的情况,不需要再判断left或者right是否为null了
var maxDepth = function(root) {
if (!root) return 0;
return Math.max(maxDepth(root.right), maxDepth(root.left)) + 1;
};
迭代的思路:可以每次都把当前层的节点的子节点丢进一个数组,然后判断这个数组的长度,如果长度大于0则说明有下一层。下一轮循环就遍历这个数组,重复,最后没有子节点时跳出循环
var maxDepth = function(root) {
if (!root) return 0;
var v = [root],
r = [],
res = 1;
while (v.length) {
v.forEach((i) => {
if (i.left) r.push(i.left);
if (i.right) r.push(i.right);
});
if (r.length) {
v = r;
r = [];
res++;
} else {
break;
}
}
return res;
};
2.二叉树的层次遍历
题目:给定一个二叉树,返回其节点值自底向上的层次遍历。 (即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)
思路:和上一题的循环解法非常像,每次把结果放到最前面即可。
var levelOrderBottom = function(root) {
if (!root) return [];
var v = [root],
r = [];
while (true) {
var a = [],
t = [];
v.forEach((i) => {
t.push(i.val);
if (i.left) {
a.push(i.left);
}
if (i.right) {
a.push(i.right);
}
});
r.unshift(t);
if (a.length) {
v = a;
} else {
break;
}
}
return r;
};
3.将有序数组转换为二叉搜索树
题目:
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。
本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。
思路:分治法,想象一下,每次取中间节点,左边的节点组成一颗子树,放在这个节点的左边,右边的节点组成一颗子树,放在这个节点的右边,然后左右的节点数组递归调用,知道长度小于2。.长度为0时直接返回null,长度为1时返回这个节点。最终就得到了二叉树
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* @param {number[]} nums
* @return {TreeNode}
*/
var sortedArrayToBST = function(nums) {
let l = nums.length;
if (!l) return null;
if (l === 1) return new TreeNode(nums[0]);
const middle = Math.floor(l / 2);
const mn = new TreeNode(nums[middle]);
mn.left = sortedArrayToBST(nums.slice(0, middle));
mn.right = sortedArrayToBST(nums.slice(middle + 1));
return mn;
};
4.平衡二叉树
题目:
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。
思路:递归求解,在每次执行函数时,判断某个节点的左右两个子树各自是否高度平衡,然后判断两个子树之间的高度是否只相差1.
const a = (v) => {
if (!v) return 0;
return Math.max(a(v.left), a(v.right)) + 1;
};
var isBalanced = function(root) {
if (!root) return true;
return (
isBalanced(root.left) &&
isBalanced(root.right) &&
Math.abs(a(root.left) - a(root.right)) < 2
);
};
5.二叉树的最小深度
题目:
给定一个二叉树,找出其最小深度。
最小深度是从根节点到最近叶子节点的最短路径上的节点数量。
说明: 叶子节点是指没有子节点的节点。
思路:这个和之前的一个求最大深度的很像,递归求解即可
var minDepth = function(root) {
if(!root)return 0
if(root.left&&root.right){
return Math.min(minDepth(root.left),minDepth(root.right))+1
}else if(root.left){
return minDepth(root.left)+1
}else{
return minDepth(root.right)+1
}
};
循环解法:
var minDepth = function(root) {
if (!root) return 0;
let stack = [root];
let res = 1,
item;
while (true) {
let l = stack.length;
for (let i = 0; i < l; i++) {
item = stack.shift();
if (!item.left && !item.right) {
return res;
} else {
if (item.left) stack.push(item.left);
if (item.right) stack.push(item.right);
}
}
res++;
}
};
递归的优化:不需要遍历树的每个节点,只需要在遍历的时候保存之前递归的最小结果,然后在递归过程中如果当前深度已经超过这个值,则直接停止这个子树的递归。
var min = (node, res, currD = 0) => {
currD++;
if (currD >= res.v) {
return;
}
if (!node.left && !node.right && currD < res.v) {
res.v = currD;
}
if (node.left) min(node.left, res, currD);
if (node.right) min(node.right, res, currD);
};
var minDepth = function(root) {
if (!root) return 0;
var res = { v: Infinity };
min(root, res);
return res.v;
};