根到叶路径上的不足节点
给你二叉树的根节点 root 和一个整数 limit ,请你同时删除树中所有 不足节点 ,并返回最终二叉树的根节点。
假如通过节点 node 的每种可能的 “根-叶” 路径上值的总和全都小于给定的 limit,则该节点被称之为 不足节点 ,需要被删除。
叶子节点,就是没有子节点的节点。
示例 1:
输入: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:
输入: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:
输入: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
}