题目链接:404. 左叶子之和
题目描述
给定二叉树的根节点 root
,返回所有左叶子之和。
示例 1:
输入: root = [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中,有两个左叶子,分别是 9 和 15,所以返回 24
示例 2:
输入: root = [1] 输出: 0
提示:
- 节点数在
[1, 1000]
范围内 -1000 <= Node.val <= 1000
文章讲解:代码随想录
视频讲解:二叉树的题目中,总有一些规则让你找不到北 | LeetCode:404.左叶子之和_哔哩哔哩_bilibili
题解1:递归法
思路:后序遍历,递归的获取左右子树的左叶子节点和加起来,即为整个树的左叶子节点和。
递归分析:
- 确定递归函数的参数和返回值:参数为当前遍历的节点,返回值为以当前节点为根节点的子树的左叶子之和。
- 确定递归终止条件:当前遍历的节点为空时,返回0;当前遍历的节点为叶子节点时,也返回0(在遍历左叶子节点的父节点时才能知道这个叶子节点是左叶子,计算左叶子之和的逻辑在那里处理)。
- 确定单层递归逻辑:先求左子树的左叶子之和,再求出右子树的左叶子之和,加起来即为当前子树的左叶子之和。若左子树为叶子节点,左子树的左叶子之和即为左叶子节点的值,否则递归的计算左子树的左叶子之和。
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var sumOfLeftLeaves = function(root) {
if (!root || !root.left && !root.right) {
return 0;
}
return (root.left && !root.left.left && !root.left.right ? root.left.val : sumOfLeftLeaves(root.left)) + sumOfLeftLeaves(root.right); // 后序遍历
};
分析:时间复杂度为 O(n),空间复杂度为 O(logn)。
题解2:迭代法
思路:前序遍历,遇到左叶子节点则记录下左叶子节点的值,遍历到左叶子节点的父节点时才能知道这个节点是左叶子节点。
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var sumOfLeftLeaves = function(root) {
let res = 0;
const stack = [];
if (root) {
stack.push(root);
}
while (stack.length > 0) {
const node = stack.pop();
if (node.left && !node.left.left && !node.left.right) {
res += node.left.val; // 中
}
node.right && stack.push(node.right); // 右
node.left && stack.push(node.left); // 左
}
return res;
};
分析:时间复杂度为 O(n),空间复杂度为 O(logn)。
收获
进一步加深了对二叉树遍历的理解,可以使用递归法和迭代法来遍历二叉树。