【算法17天:Day17】第六章二叉树 LeetCode 左叶子之和(404)

61 阅读2分钟

题目三:

image.png

解法一:(递归)

解题思路:这个题我想自己写,大致思路对了,就是对于左叶子没定义好,导致没写出来。这个题的递归思路就是:使用闭包定义sum,递归逻辑中,遇到当前节点的左节点是左叶子节点时,就加上当前节点的左叶子结点数值,使用前中后序递归遍历都可。

左叶子的明确定义:节点A的左孩子不为空,且左孩子的左右孩子都为空(说明是叶子节点),那么A节点的左孩子为左叶子节点。 不能判断本结点是不是左叶子结点,需要通过节点的父节点来判断其左孩子是不是左叶子。

平时我们解二叉树的题目时,已经习惯了通过节点的左右孩子判断本节点的属性,而本题我们要通过节点的父节点判断本节点的属性。

var sumOfLeftLeaves = function(root) {
    let sum = 0
    var leftNodesSum = function(cur) {
        // 遇到空结点 
        if (cur === null) return 0 
        // 遇到左孩子结点
        if (cur.left !== null && cur.left.left === null && cur.left.right === null) {
            sum += cur.left.val
        }
        leftNodesSum(cur.left)
        leftNodesSum(cur.right)
    }
    leftNodesSum(root)
    return sum 
};

解法二:(迭代法)

解题思路:一直迭代遍历每一个结点,如果是左叶子结点就算入总和,可以使用前中后以及层序遍历。

var sumOfLeftLeaves = function(root) {
    if (root === null) return 0
    let stack = [root]
    let sum = 0
    while(stack.length) {
        let node = stack.pop()
        if (node.left !== null && node.left.left === null  && node.left.right === null) {
            sum += node.left.val
        }
        node.right && stack.push(node.right)
        node.left && stack.push(node.left)
    }
    return sum
};

解法三:(参考他人)

写一个辅助函数,求当前子树的所有左叶子之和,有一个参数 isLeft:当前子树是否为左子树。

当遍历的是 null 节点,返回 0。

当遍历的是叶子节点,根据 isLeft 判断,是左叶子节点就返回 root.val,不是就返回 0。

当遍历到别的节点,递归它们的左、右子树,isLeft 分别传 true 和 false,返回值相加并返回,

const sumOfLeftLeaves = (root) => {

  const dfs = (root, isLeft) => {
    if (root == null) return 0;
    if (root.left == null && root.right == null) {
      if (isLeft) return root.val;
      return 0;
    }
    return dfs(root.left, true) + dfs(root.right, false);
  };

  return dfs(root, false);
};

也可以把 isLeft 拿出来作为一个标识变量:

const sumOfLeftLeaves = (root) => {
  if (root == null) return 0;
  let sum = 0;
  let isLeft = false;

  const dfs = (root) => {
    if (root.left == null && root.right == null) {
      if (isLeft) sum += root.val;
      return;
    }
    if (root.left) {
      isLeft = true;
      dfs(root.left);
    }
    if (root.right) {
      isLeft = false;
      dfs(root.right);
    }
  };
  
  dfs(root);
  return sum;
};