110. 平衡二叉树
题目:
给定一个二叉树,判断它是否是高度平衡的二叉树。
本题中,一棵高度平衡二叉树定义为:一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。
示例:
输入:root = [3,9,20,null,null,15,7]
输出:true
解题思路:
平衡二叉树需要比较的是高度,所以使用后序遍历,递归三部曲:
- 明确递归函数的参数和返回值:参数是当前传入节点,返回值是以当前传入节点为根节点的树的高度。
- 明确终止条件:递归的过程中依然是遇到空节点了为终止,返回0,表示当前节点为根节点的树高度为0。
- 明确单层递归的逻辑:分别求出其左右子树的高度,然后如果差值小于等于1,则返回当前二叉树的高度,否则返回-1,表示已经不是二叉平衡树了。如果已经有一边子树的高度是-1,那就直接向上返回-1直到最上层。
var isBalanced = function (root) {
const getHeight = (node) => {
if (!node) {
return 0;
}
const leftHeight = getHeight(node.left);
if (leftHeight === -1) {
return -1;
}
const rightHeight = getHeight(node.right);
if (rightHeight === -1) {
return -1;
}
if (Math.abs(leftHeight - rightHeight) > 1) {
return -1;
}
return 1 + Math.max(leftHeight, rightHeight);
}
const res = getHeight(root);
return res === -1 ? false : true;
};
257. 二叉树的所有路径
题目:
给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。
叶子节点 是指没有子节点的节点。
示例:
输入:root = [1,2,3,null,5]
输出:["1->2->5","1->3"]
解题思路:
这道题目要求从根节点到叶子的路径,所以需要前序遍历,这样才方便让父节点指向孩子节点,找到对应的路径。在这个过程中,要不断回溯到上层节点来找下一条路径。
根据递归三部曲:
- 确定递归函数的参数和返回值:传入根节点即可,路径可以用闭包的形式来记录。
- 确定递归终止条件:这道题不需要到为null的节点,只要到叶子结点即可。
- 确定单层递归逻辑:因为是前序遍历所以要先处理中间节点,中间节点要在加入完整路径之前就加入到路径数组中。之后判断左右子树需要对节点是否为空做判断,因为前置没有过滤空节点的情况,最后还需要注意在递归完成后对路径数组进行pop来回溯到上层节点。
var binaryTreePaths = function (root) {
if (!root) {
return [];
}
const res = [];
const path = [];
const traversal = (node) => {
path.push(node.val);
if (node.left === null && node.right === null) {
res.push(path.join('->'));
return;
}
if (node.left) {
traversal(node.left);
path.pop();
}
if (node.right) {
traversal(node.right);
path.pop();
}
}
traversal(root);
return res;
};
404. 左叶子之和
题目:
给定二叉树的根节点 root ,返回所有左叶子之和。
示例:
输入: root = [3,9,20,null,null,15,7]
输出: 24
解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
解题思路:
左叶子结点是左孩子不为空但是左孩子的左右孩子都为空,这种情况下的左孩子就是左叶子结点。这道题因为需要一层一层的向上来传递加和,所以还是使用后序遍历。
递归三部曲:
- 确定递归函数的参数和返回值:传入树的根节点,返回左叶子数值之和。
- 确定终止条件:遍历到空节点,左叶子值为0。遍历到叶子结点,左叶子值也会是0。
- 确定单层递归的逻辑:遍历到左叶子节点的时候记录数值,右叶子节点可以直接取递归的值。
var sumOfLeftLeaves = function (root) {
const traversal = (node) => {
if (!node) {
return 0;
}
if (node.left === null && node.right === null) {
return 0;
}
let leftNum = traversal(node.left);
if (node.left !== null && node.left.left === null && node.left.right === null) {
leftNum = node.left.val;
}
let rightNum = traversal(node.right);
const sum = leftNum + rightNum;
return sum;
}
return traversal(root);
};