leetcode 1080 根到叶路径上的不足节点(深度优先DFS、广度优先BFS)

130 阅读1分钟

根到叶路径上的不足节点

给你二叉树的根节点 root 和一个整数 limit ,请你同时删除树中所有 不足节点 ,并返回最终二叉树的根节点。

假如通过节点 node 的每种可能的 “根-叶” 路径上值的总和全都小于给定的 limit,则该节点被称之为 不足节点 ,需要被删除。

叶子节点,就是没有子节点的节点。

示例 1:

img

输入:root = [1,2,3,4,-99,-99,7,8,9,-99,-99,12,13,-99,14], limit = 1
输出:[1,2,3,4,null,null,7,8,9,null,14]

示例 2:

img

输入:root = [5,4,8,11,null,17,4,7,1,null,null,5,3], limit = 22
输出:[5,4,8,11,null,17,4,7,null,null,null,5]

示例 3:

img

输入:root = [1,2,-3,-5,null,4,null], limit = -1
输出:[1,null,-3,4]

提示:

  • 树中节点数目在范围 [1, 5000]

  • -105 <= Node.val <= 105

  • -109 <= limit <= 109

构建二叉树

该题示例只给了数组类型输入,没有二叉树结构的实现,分析示例的数组结构可知,数组是树的广度优先遍历的结果,故通过广度优先遍历生成对应的二叉树,代码如下:

class TreeNode {
  constructor(val) {
    this.val = val
    this.left = null
    this.right = null
  }
}

function genTree(li) {
  if (li.length === 0) {
    return null
  }
  let t = new TreeNode(li[0])
  let liTree = [t]
  let cur = liTree.shift()
  let setLeft = false
  let setRight = false
  for (let i = 1; i < li.length; i++) {
    if (!setLeft) {
      cur.left = genTreeNode(li[i], liTree)
      setLeft = true
    } else if (!setRight) {
      cur.right = genTreeNode(li[i], liTree)
      setRight = true
    } else {
      cur = liTree.shift()
      cur.left = genTreeNode(li[i], liTree)
      setLeft = true
      setRight = false
    }
  }
  return t
}
function genTreeNode(val, li) {
  if (val === null) {
    return val
  } else {
    let t = new TreeNode(val)
    li.push(t)
    return t
  }
}

解题

白话解释下该题的需求:

  • 左叶子节点的“根-叶” 路径和小于limit删除左叶子节点
  • 右叶子节点的“根-叶” 路径和小于limit删除右叶子节点
  • 左、右叶子节点的“根-叶” 路径和都小于limit删除根节点

需要求“根-叶”节点的路径和,故采用深度优先遍历树节点,基于上面的3种场景实现逻辑,代码实现:

/**
 * 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
 * @param {number} limit
 * @return {TreeNode}
 */
var sufficientSubset = function (root, limit) {
  let haveSufficient = checkSufficientLeaf(root, 0, limit)
  return haveSufficient ? root : null
}
var checkSufficientLeaf = function (node, prevSum, limit) {
  if (node === null) {
    return false
  }
  if (node.left === null && node.right === null) {
    return node.val + prevSum >= limit
  }
  let haveSufficientLeft = checkSufficientLeaf(node.left, node.val + prevSum, limit)
  let haveSufficientRight = checkSufficientLeaf(node.right, node.val + prevSum, limit)
  if (!haveSufficientLeft) {
    node.left = null
  }
  if (!haveSufficientRight) {
    node.right = null
  }
  return haveSufficientLeft || haveSufficientRight
}