删点成林

94 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招系列活动-刷题打卡任务,点击查看活动详情

一、题目描述

给出二叉树的根节点 root,树上每个节点都有一个不同的值。
如果节点值在 to_delete 中出现,我们就把该节点从树上删去,最后得到一个森林(一些不相交的树构成的集合)。
返回森林中的每棵树。你可以按任意顺序组织答案。 示例 1:

输入:root = [1,2,3,4,5,6,7], to_delete = [3,5]
输出:[[1,2,null,4],[6],[7]]

示例 2:

输入:root = [1,2,4,null,3], to_delete = [3]
输出:[[1,2,4]]

提示:

树中的节点数最大为 1000
每个节点都有一个介于 1  1000 之间的值,且各不相同。
to_delete.length <= 1000
to_delete 包含一些从 1  1000、各不相同的值。

二、思路分析

分析一下本题的题目描述,我们可以知道题目会给出两个输入参数,分别是root和to_delete,root为树的根节点,to_delete为需要删除的节点,以示例1为例,我们将节点3和5删除后,6、7和3之间的联系也即断开,如下图所示,原本的数就断成了如下三截: image.png

  • 判断根节点是否被删除 根节点不在删除列表中则将根节点放入结果的树集合中去。
if(!to_delete.includes(root.val)) treeArr.push(root);
  • 删除树中需要删除的节点 判断当前节点的子节点是否在删除列表中,如果在则将其子节点都放入到结果的树集合中去,并将当前节点和其父节点的连接断开。 注意: 删除子节点是并不能直接将该节点置为null,而是需要将其与父节点的联系断开,因为树节点之间是通过指针构成联系的。
let getTreeArr = function(r,pre = null,isLeft = false){
    if(!r) return;
    let ind = to_delete.indexOf(r.val);
    if(ind !== -1){
        if(r.left && !to_delete.includes(r.left.val)) treeArr.push(r.left);
        if(r.right && !to_delete.includes(r.right.val)) treeArr.push(r.right);
        to_delete.splice(ind,1);
    }
    getTreeArr(r.left,r,true);
    getTreeArr(r.right,r);
    if(ind !== -1){
        if(!pre) return;
        isLeft ? pre.left = null : pre.right = null;
    }
}

三、AC代码

/**
 * 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[]} to_delete
 * @return {TreeNode[]}
 */
var delNodes = function(root, to_delete) {
    let treeArr = [];
    if(!to_delete.includes(root.val)) treeArr.push(root);
    let getTreeArr = function(r,pre = null,isLeft = false){
        if(!r) return;
        let ind = to_delete.indexOf(r.val);
        if(ind !== -1){
            if(r.left && !to_delete.includes(r.left.val)) treeArr.push(r.left);
            if(r.right && !to_delete.includes(r.right.val)) treeArr.push(r.right);
            to_delete.splice(ind,1);
        }
        getTreeArr(r.left,r,true);
        getTreeArr(r.right,r);
        if(ind !== -1){
            if(!pre) return;
            isLeft ? pre.left = null : pre.right = null;
        }
    }
    getTreeArr(root);
    return treeArr;
};