【LetMeFly】1110.删点成林
力扣题目链接:https://leetcode.cn/problems/delete-nodes-and-return-forest/
给出二叉树的根节点 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 <= 1000to_delete包含一些从1到1000、各不相同的值。
方法一:深度优先搜索DFS
写一个函数dfs(root),返回root节点是否需要保留,并递归判断root的左右子是否需要保留。
- 如果root不需要保留,但左右子中有需要保留的,则需要保留的字节的将称为新的根节点(加入到答案的根节点数组中)。
 - 否则(root需要保留),如果root的子节点不需要保留,则修改root的子节点为空。
 
就可以了。
- 时间复杂度 O ( n ) O(n) O(n),其中 n n n是二叉树节点个数
 - 空间复杂度 O ( n ) O(n) O(n)
 
AC代码
C++
class Solution {
private:
    vector<TreeNode*> ans;
    unordered_set<int> toDelete;
    bool dfs(TreeNode* root) {  // 是否需要保留root
        if (!root) {
            return false;
        }
        bool keepLeft = dfs(root->left);
        bool keepRight = dfs(root->right);
        if (toDelete.count(root->val)) {  // 删root
            if (keepLeft) {
                ans.push_back(root->left);
            }
            if (keepRight) {
                ans.push_back(root->right);
            }
            // delete root;
            return false;
        }
        else {
            root->left = keepLeft ? root->left : nullptr;
            root->right = keepRight ? root->right : nullptr;
            return true;
        }
    }
public:
    vector<TreeNode*> delNodes(TreeNode* root, vector<int>& to_delete) {
        for (int t : to_delete) {
            toDelete.insert(t);
        }
        if (dfs(root)) {
            ans.push_back(root);
        }
        return ans;
    }
};
 
Python
# from typing import Optional, List
class Solution:
    def dfs(self, root: Optional[TreeNode]) -> bool:
        if not root:
            return False
        keepLeft = self.dfs(root.left)
        keepRight = self.dfs(root.right)
        if root.val in self.toDelete:  # 删root
            if keepLeft:
                self.ans.append(root.left)
            if keepRight:
                self.ans.append(root.right)
            return False
        else:
            root.left = root.left if keepLeft else None
            root.right = root.right if keepRight else None
            return True
    
    def delNodes(self, root: Optional[TreeNode], to_delete: List[int]) -> List[TreeNode]:
        self.ans = []
        self.toDelete = set()
        for t in to_delete:
            self.toDelete.add(t)
        if self.dfs(root):
            self.ans.append(root)
        return self.ans
 
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/130941100












![CodeForces..李华和迷宫.[简单].[找规律]](https://img-blog.csdnimg.cn/193c1f0bc179472ea655e347c4fd71c3.png)






