144. 二叉树的前序遍历
给你二叉树的根节点 root ,返回它节点值的前序遍历。
示例:输入:root = [1,null,2,3],输出:[1,2,3]。
❝前序遍历是二叉树遍历的一种,首先访问根节点,然后遍历左子树,最后遍历右子树,可以记作根左右。
❞
解题思路:「由于二叉树的定义本身就是递归的,所以按照根左右的顺序递归记录节点值即可」。
时间复杂度:O(n),空间复杂度:O(n)。
const help = (root, ans) => {
if (!root) {
return;
}
ans.push(root.val);
// 遍历左子树
help(root.left, ans);
// 遍历右子树
help(root.right, ans);
}
const preorderTraversal = root => {
const ans = [];
help(root, ans);
return ans;
}
104. 二叉树的最大深度
给定一个二叉树,找出其最大深度。
二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。
示例:给定二叉树 [3,9,20,null,null,15,7],返回它的最大深度 3 。
解题思路:「同样利用递归的性质,二叉树的最大深度由其最大的左子树或者右子树决定,而左子树的最大深度又由其左子树和右子树决定...」。
时间复杂度:O(n),空间复杂度:O(height)。
const maxDepth = root => {
if (!root) {
return 0;
}
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
}
226. 翻转二叉树
给你一棵二叉树的根节点 root ,翻转这棵二叉树,并返回其根节点。
示例:输入:root = [4,2,7,1,3,6,9],输出:[4,7,2,9,6,3,1]。
解题思路:「同样利用二叉树的递归特性,翻转二叉树本质上就是交换其左右子树,并且这里采用 ES6 中数组解构赋值的特性,可以省去临时变量,让代码更加优雅」。
时间复杂度:O(n),空间复杂度:O(n)。
const invertTree = (root) => {
if (!root) {
return null;
}
[root.left, root.right] = [root.right, root.left];
invertTree(root.left);
invertTree(root.right);
return root;
}
112. 路径总和
给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。
❝叶子节点是指没有子节点的节点。
❞
示例:输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22,输出:true。
解题思路:「和值问题,可以通过减法来降低其复杂度,那么在递归的过程需要不断地减去当前节点的值,从而把问题转化为判断叶子节点的值是否等于 sum」。
时间复杂度:O(n),空间复杂度:O(n)。
const hasPathSum = (root, sum) => {
if (!root) {
return false;
}
if (!root.left && !root.right) {
return root.val === sum;
}
const reset = sum - root.val;
const x = hasPathSum(root.left, reset);
const y = hasPathSum(root.right, reset);
return x || y;
}
写在最后
「感谢您能耐心地读到这里,如果本文对您有帮助,欢迎点赞、分享、或者关注下方的公众号哟。」