Medium草稿★★★★★O(n) 時間 · O(h) 空間
TreeBSTDFSReverse Inorder
Patterns🌳 樹形 DFS
尚未複習過

解法已隱藏 — 先讀題目敘述、自己想想看,再點上方按鈕揭曉。

538Convert BST to Greater TreeTreesMediumTrees

給定一棵 BST 的根節點,將每個節點的值替換為原 BST 中所有大於或等於該節點值的節點值之和。

Example:

Input: root = [4,1,6,0,2,5,7,null,null,null,3,null,null,null,8] Output: [30,36,21,36,35,26,15,null,null,null,33,null,null,null,8]

Intuition

TIP

反向中序遍歷(右 -> 根 -> 左)就是從大到小遍歷,累加即可。

Approaches

1. Reverse Inorder (recursive) — O(n) / O(h)
  • Idea: 反向中序遍歷,用全域變數累加,每個節點更新為累加和
  • Time: O(n)
  • Space: O(h),h 為樹高
class Solution {
    private var sum = 0

    fun convertBST(root: TreeNode?): TreeNode? {
        sum = 0
        reverseInorder(root)
        return root
    }

    private fun reverseInorder(node: TreeNode?) {
        if (node == null) return
        reverseInorder(node.right)
        sum += node.`val`
        node.`val` = sum
        reverseInorder(node.left)
    }
}
⭐ 2. Reverse Inorder (iterative) — O(n) / O(h)
  • Idea: 用堆疊模擬反向中序遍歷,先一路向右,然後處理當前節點,再轉左
  • Time: O(n)
  • Space: O(h)
class Solution {
    fun convertBST(root: TreeNode?): TreeNode? {
        val stack = ArrayDeque<TreeNode>()
        var sum = 0
        var current = root
        while (current != null || stack.isNotEmpty()) {
            while (current != null) {
                stack.addLast(current)
                current = current.right
            }
            current = stack.removeLast()
            sum += current.`val`
            current.`val` = sum
            current = current.left
        }
        return root
    }
}
Morris Traversal (O(1) space)

可以用 Morris 遍歷達到 O(1) 空間,但程式碼較複雜,面試中反向中序遍歷已經足夠。Morris 遍歷利用葉節點的空指標建立臨時鏈接,省去堆疊的空間開銷。

🔑 Takeaways