其他分享
首页 > 其他分享> > 【树】力扣1110:删点成林

【树】力扣1110:删点成林

作者:互联网

给出二叉树的根节点 root,树上每个节点都有一个不同的值。

如果节点值在 to_delete 中出现,我们就把该节点从树上删去,最后得到一个森林(一些不相交的树构成的集合)。

返回森林中的每棵树。你可以按任意顺序组织答案。

示例:

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

第一次遇到没有官方题解的题~

输入是一个整数二叉树和一个一维整数数组,输出一个数组,每个位置存储一个子树(的根节点)。

二叉树的题大多可以用递归,从而想到深度优先搜索DFS。

后序遍历

对于被删除节点类型,可以分情况进行分析:

为了得到这个结果集,每个结点需要做什么?

在什么时候做这些事?

那么不妨采用后序遍历的方式,定义一个删除函数:删除以 node 为根结点的树中结点值出现在 to_delete 中的结点,更新结果 ans,并返回删除后新的根结点。

在执行这个删除函数之前,需要做什么准备工作呢?


时间复杂度:O(N),其中 N 为树的结点个数。

空间复杂度:O(N)。

前序遍历

如果在递归过程中修改二叉树结构,必须要让父结点接收递归函数的返回值。

可以通过函数参数传递父结点传递的数据,所以可以在前序位置判断是否得到了一个新的根结点。

@ JavaScript

/**
 * @param {TreeNode} root
 * @param {number[]} to_delete
 * @return {TreeNode[]}
 */
var delNodes = function (root, to_delete) {
  let delSet = new Set();
  // 记录森林的根节点
  let res = [];
  if (root == null) return [];
  for (let d of to_delete) {
    delSet.add(d);
  }
  // 定义:输入一棵二叉树,删除 delSet 中的节点,返回删除完成后的根节点
  const doDelete = (root, hasParent) => {
    if (root == null) return null;
    // 判断是否需要被删除
    let deleted = delSet.has(root.val);
    if (!deleted && !hasParent) {
      // 没有父节点且不需要被删除,就是一个新的根节点
      res.push(root);
    }
    // 去左右子树进行删除
    root.left = doDelete(root.left, !deleted);
    root.right = doDelete(root.right, !deleted);
    // 如果需要被删除,返回 null 给父节点
    return deleted ? null : root;
  };
  doDelete(root, false);
  return res;
};

作者:angela-x
链接:https://leetcode.cn/problems/delete-nodes-and-return-forest/solution/qian-xu-bian-li-lai-jie-jue-shan-dian-ch-l3h4/

标签:结点,return,删除,力扣,1110,删点,root,节点,delete
来源: https://www.cnblogs.com/Jojo-L/p/16487901.html