1. 题目
给出二叉树的根节点 root,树上每个节点都有一个不同的值。
如果节点值在 to_delete 中出现,我们就把该节点从树上删去,最后得到一个森林(一些不相交的树构成的集合)。
返回森林中的每棵树。你可以按任意顺序组织答案。
示例:
输入:root = [1,2,3,4,5,6,7], to_delete = [3,5]
输出:[[1,2,null,4],[6],[7]]提示:
树中的节点数最大为 1000。
每个节点都有一个介于 1 到 1000 之间的值,且各不相同。
to_delete.length <= 1000
to_delete 包含一些从 1 到 1000、各不相同的值。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/delete-nodes-and-return-forest
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2. 解题
- 要删除的放入哈希表,方便快速查找
- 递归遍历,记录父节点,和左右方向
- 如果要删除,断开父节点,子节点,遍历子节点
- 不删除,且父节点为空,加入答案
class Solution {unordered_set<int> s;vector<TreeNode*> ans;
public:vector<TreeNode*> delNodes(TreeNode* root, vector<int>& to_delete) {if(!root)return {};for(int del : to_delete)s.insert(del);//哈希快速查找order(root, NULL, 0);return ans;}void order(TreeNode* root, TreeNode* father, int dir){ //参数,当前节点,其父节点,是父节点的左节点还是右节点if(!root)return;if(s.count(root->val))//root需要删除{if(father)//要删除的节点有父节点{if(dir==0)//是左边过来的father->left = NULL;//断开与父节点的链接elsefather->right = NULL;}TreeNode *l = root->left, *r = root->right;//当前节点的左右子节点root->left = NULL;//断开子的链接root->right = NULL;//断开子的链接order(l, NULL, 0);//遍历左子,其父节点断开了,为空,第三个参数随意order(r, NULL, 0);//遍历右子}else//root不用删除{if(!father)//如果没有父节点了,新的树根,加入答案ans.push_back(root);order(root->left, root, 0);//遍历左子,第三个参数0表示左order(root->right, root, 1);//遍历右子,第三个参数1表示右}}
};