打卡-算法训练营-Day15 |110.平衡二叉树;257. 二叉树的所有路径; 404.左叶子之和;222.完全二叉树的节点个数

62 阅读2分钟

平衡二叉树

leetcode链接:leetcode.cn/problems/ba…

平衡二叉树:二叉树中每个节点的左右子树的高度差的绝对值不超过1

可以在104.二叉树的最大深度思路基础上加一个布尔变量,如果左右子树高度差的绝对值超过1则记为false

var isBalanced = function(root) {
  let ans = true;

  let dfs = (node) => {
    if (!node) return 0;

    let leftHeight = dfs(node.left);
    let rightHeight = dfs(node.right);

    if (Math.abs(leftHeight - rightHeight) > 1) {
      ans = false;
    }

    return 1 + Math.max(leftHeight, rightHeight);
  };

  dfs(root);
  return ans;
};

二叉树的所有路径

leetcode链接:leetcode.cn/problems/bi…

收集路径采用前序遍历,非叶子节点将节点元素收集起来,遇到叶子节点则把收集到的路径输出

要注意的是,将当前节点的左右子树处理完后,要把当前元素的值弹出

var binaryTreePaths = function(root) {
  let result = [];
  let temp = [];

  let dfs = (node) => {
    if (!node) return;
    // 前序遍历,收集节点的值
    temp.push(node.val);
    if (node.left === null && node.right === null) {
      // 说明当前节点是叶子节点,输出路径结果
      result.push(temp.join("->"));
      temp.pop();
      return;
    }
    dfs(node.left);
    dfs(node.right);
    // 处理完当前节点的左右子树后,将当前节点元素弹出
    temp.pop();
  };
  dfs(root);
  return result;
};

左叶子之和

leetcode链接:leetcode.cn/problems/su…

左叶子:

root = [3,9,20,null,null,15,7],左叶子节点是9和15

root = [1,2,3,4,5],左叶子节点是4(注意没有2,2是左节点,但不是叶子节点)

当 node.left === null && node.right === null时,说明当前节点是叶子节点,再多用一个isLeft参数来判断是不是左节点

var sumOfLeftLeaves = function(root) {
  let result = 0;
  
  let dfs = (node, isLeft) => {
    if (!node) return;
    
    if (node.left === null && node.right === null && isLeft) {
      result += node.val;
    }
    
    dfs(node.left, true);
    dfs(node.right, false);
  };
  
  dfs(root, false);
  
  return result;
};

完全二叉树的节点个数

可以利用满二叉树的特性减少不必要节点的遍历

满二叉树的节点计算:2^k - 1

当前节点到最左边节点的距离等于到最右边节点的距离说明是满二叉树,不用考虑中间节点为空的情况,因为题目明确说给出的是完全二叉树,节点一定是从左往右排列

var countNodes = function(root) {
    // 第一个终止条件
    if (!root) return 0;

    // 第二个终止条件,以当前节点为根节点的二叉树是满二叉树
    let left = root.left;
    let right = root.right;
    let leftDeep = 1;
    let rightDeep = 1;
    while (left) {
        left = left.left;
        leftDeep++;
    }
    while (right) {
        right = right.right;
        rightDeep++;
    }
    // 左边深度和右边深度相等说明是满二叉树
    if (leftDeep === rightDeep) {
        return Math.pow(2, leftDeep) - 1;
    }

    // 后序遍历,单层递归逻辑
    let leftNodes = countNodes(root.left);
    let rightNodes = countNodes(root.right);
    return leftNodes + rightNodes + 1;
};