題目描述
給你一棵以 root 爲根的二叉樹和一個整數 target ,請你刪除所有值爲 target 的 葉子節點 。
注意,一旦刪除值爲 target 的葉子節點,它的父節點就可能變成葉子節點;如果新葉子節點的值恰好也是 target ,那麼這個節點也應該被刪除。
也就是說,你需要重複此過程直到不能繼續刪除。
輸入:root = [1,2,3,2,null,2,4], target = 2
輸出:[1,null,3,null,4]
解釋:
上面左邊的圖中,綠色節點爲葉子節點,且它們的值與 target 相同(同爲 2 ),它們會被刪除,得到中間的圖。
有一個新的節點變成了葉子節點且它的值與 target 相同,所以將再次進行刪除,從而得到最右邊的圖。
輸入:root = [1,3,3,3,2], target = 3
輸出:[1,3,null,null,2]
輸入:root = [1,2,null,2,null,2], target = 2
輸出:[1]
解釋:每一步都刪除一個綠色的葉子節點(值爲 2)。
示例 4:
輸入:root = [1,1,1], target = 1
輸出:[]
示例 5:
輸入:root = [1,2,3], target = 1
輸出:[1,2,3]
提示:
1 <= target <= 1000
每一棵樹最多有 3000 個節點。
每一個節點值的範圍是 [1, 1000] 。
思路
由於我們需要刪除所有值爲 target 的葉子節點,那麼我們的操作順序應當從二叉樹的葉子節點開始,逐步向上直到二叉樹的根爲止。因此我們可以使用遞歸的方法遍歷整顆二叉樹,並在 回溯 時進行刪除操作。這樣對於二叉樹中的每個節點,它的子節點一定先於它被操作。這其實也就是二叉樹的 後序 遍歷。
具體地,當我們回溯到某個節點 root 時,如果 root的左右孩子均不存在(這裏有兩種情況,一是節點 root的孩子本來就不存在,二是節點 root 的孩子變成了葉子節點並且值爲 target,導致其被刪除,因爲孩子節點一定先於root節點進行操作),並且值爲 target,那麼我們要刪除節點 root,遞歸函數的返回值爲空節點;如果節點 root不需要被刪除,那麼遞歸函數的返回值爲節點 root本身。
時間複雜度:O(N)
空間複雜度:O(N)
代碼
class Solution {
public TreeNode removeLeafNodes(TreeNode root, int target) {
if (root == null) return null;
root.left = removeLeafNodes(root.left, target);
root.right = removeLeafNodes(root.right, target);
// 回溯:若爲葉子節點則刪除
if (root.left == root.right) {
if (root.val == target)
// 刪除
return null;
}
return root;
}
}
執行用時:0 ms, 在所有 Java 提交中擊敗了100.00%的用戶
內存消耗:39.4 MB, 在所有 Java 提交中擊敗了100.00%的用戶