leetcode_1110 删点成林

72 阅读1分钟

要求

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

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

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

示例 1:

image.png

输入: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、各不相同的值。

核心代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def delNodes(self, root: TreeNode, to_delete: List[int]) -> List[TreeNode]:
        res = list()
        to_delete = set(to_delete)
        def preOrder(root,n_root):
            if root:
                if root.val not in to_delete and n_root:
                    res.append(root)
                root.left = preOrder(root.left,root.val in to_delete)
                root.right = preOrder(root.right,root.val in to_delete)
                return None if root.val in to_delete else root
        
        preOrder(root,True)
        return res

image.png

解题思路:对于树的问题,我们一般首先思考递归解法,对于递归解法我们首先思考边界条件。对于这个问题,我们观察一下最后留下的森林,实际上在存储的时候我们保存的这些树的根节点。那么什么样的根节点需要保留呢?父亲节点被删除自己没有被删除。要注意的是,虽然我们知道了最后保留哪些节点,但是我们还有一个操作需要完成,那就是删除节点的操作。这个使用递归非常简单,边界条件是当root == None的时候我们返回None即可,否则的话,我们的root->left=f(root->left);root->right=f(root->right),其中f函数就是我们的删除节点操作函数。最后代码也非常简洁。