題意
給定一個二元樹的根節點 root,樹中的每個的節點都有唯一的值。
另給定一個陣列 to_delete,其中包含一些值,如果節點的值在 to_delete 中,我們就將該節點從樹中刪除,最後會得到一個森林(一些不相交的樹構成的集合)。
請返回在刪除 to_delete 中的節點後,森林中的每棵樹的根節點。可以按任意順序返回結果。
思路:深度優先搜尋(DFS)
由於我們需要遍歷整個樹,並根據每個節點是否在 to_delete 中進行刪除,因此可以使用 深度優先搜尋(DFS) 來解決這個問題。
定義一個 DFS 函數 dfs(root,is_root),其中 root 表示當前節點,is_root 表示當前節點是否是某棵樹的根節點。若當前節點的值在 to_delete 中,則遞迴處理其左右子樹,並將其左右子樹視為新的根節點(因為當前節點將被刪除)。最後返回 None 以表示刪除了當前節點。若當前節點的值不在 to_delete 中,則根據 is_root 判斷是否將當前節點加入答案 ans 中。然後遞迴處理其左右子樹,並更新當前節點的左右子樹。
在定義玩 dfs 函數後,我們從根節點開始調用 dfs 函數,並將 is_root 設為 True。最後返回答案 ans 。
此外,為了快速查找 to_delete 中的值,我們可以使用一個 集合(Set) to_delete_set 來存儲 to_delete 中的值。
複雜度分析
- 時間複雜度:O(n),其中 n 是二元樹的節點數,需要遍歷每個節點一次。
- 空間複雜度:O(n),遞迴深度最多為 n,此外需要額外的空間來存儲 to_delete_set 和答案 ans。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class Solution: def delNodes(self, root: Optional[TreeNode], to_delete: List[int]) -> List[TreeNode]: ans = [] to_delete_set = set(to_delete) def dfs(root: Optional[TreeNode], is_root: bool) -> Optional[TreeNode]: if not root: return None if root.val in to_delete_set: dfs(root.left, True) dfs(root.right, True) return None else: if is_root: ans.append(root) root.left = dfs(root.left, False) root.right = dfs(root.right, False) return root dfs(root, True) return ans
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public: vector<TreeNode*> delNodes(TreeNode* root, vector<int>& to_delete) { vector<TreeNode*> ans; unordered_set<int> to_delete_set(to_delete.begin(), to_delete.end()); function<TreeNode*(TreeNode*, bool)> dfs = [&](TreeNode* root, bool is_root) -> TreeNode* { if (!root) return nullptr; if (to_delete_set.count(root->val)) { dfs(root->left, true); dfs(root->right, true); return nullptr; } else { if (is_root) ans.push_back(root); root->left = dfs(root->left, false); root->right = dfs(root->right, false); return root; } }; dfs(root, true); return ans; } };
|
寫在最後
Cover photo is remixed from @吃肥皂泡泡, thanks for their work!