↓快轉到主要內容
  1. LeetCode/

LeetCode 99: Recover Binary Search Tree

·1 分鐘· ·
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2026-10-25

  • 提交紀錄:Accepted(一次通過)

解題思路
#

BST 的中序遍歷是嚴格遞增的(Tree 模板三)。兩個節點的值被交換之後,中序序列會出現「前一個比現在大」的逆序:

  • 交換的兩個節點在中序裡不相鄰:會有兩次逆序。例如 1 5 3 4 2 6,逆序是 5 > 3 和 4 > 2。被交換的是第一次逆序的前一個(5),和最後一次逆序的後一個(2)。
  • 兩個節點相鄰:只有一次逆序。例如 1 3 2 4,兩個節點都在這一次逆序裡。

所以中序走一遍,用 prev 記住上一個節點:

  • 第一次碰到 prev.val > node.val,記 first = prev。
  • 每次碰到逆序都更新 second = node。

最後交換 first 和 second 的值。兩種情況都會得到正確的兩個節點。

我的嘗試
#

一次通過。

正確解法
#

class Solution:
    def recoverTree(self, root: Optional[TreeNode]) -> None:
        self.first = None
        self.second = None
        self.prev = TreeNode(-inf)

        def inorder(node):
            if not node:
                return
            inorder(node.left)
            if self.prev.val > node.val:
                if not self.first:
                    self.first = self.prev
                self.second = node
            self.prev = node
            inorder(node.right)

        inorder(root)
        self.first.val, self.second.val = self.second.val, self.first.val

複雜度
#

時間 O(n),空間 O(h)(遞迴深度)。題目的 follow-up 要求 O(1) 空間,要用 Morris traversal 做中序。

要特別避免的錯誤
#

  • second 要在每一次逆序都更新。只在第一次逆序時記兩個節點,不相鄰的情況會換錯。
  • first 只記第一次,之後不能覆蓋。
  • prev 用值是 -inf 的哨兵節點,第一個節點就不會被當成逆序。
  • 只要交換值,不用改指標。

面試口說整理
#

BST 的中序是遞增的,兩個節點被交換後會出現逆序。不相鄰時有兩次逆序,錯的是第一次的前一個和最後一次的後一個;相鄰時只有一次,兩個都在裡面。所以我中序走一遍,第一次逆序記 first = prev,每次逆序都更新 second = node,最後交換兩個值。時間 O(n),空間 O(h);要 O(1) 空間可以改用 Morris traversal。

相關文章

LeetCode 449: Serialize and Deserialize BST
·1 分鐘
LeetCode Medium String Tree Depth-First-Search Breadth-First-Search Design Binary-Search-Tree Binary-Tree
LeetCode 449 解題筆記:BST 只要存前序,不用空節點標記;反序列化帶著上下界遞迴,O(n)
LeetCode 230: Kth Smallest Element in a BST
·1 分鐘
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 230 解題筆記:BST 的中序遍歷是由小到大,迭代中序走到第 k 個就停
LeetCode 98: Validate Binary Search Tree
·2 分鐘
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 98 解題筆記:每個節點都有一個合法範圍(下界, 上界),往左走上界變成自己、往右走下界變成自己;只比父子不夠
LeetCode 235: Lowest Common Ancestor of a Binary Search Tree
·1 分鐘
LeetCode Medium Tree Depth-First-Search Binary-Search-Tree Binary-Tree
LeetCode 235 解題筆記:p、q 都比節點小就往左,都比節點大就往右,否則(一邊一個或其中一個就是自己)這個節點就是 LCA
LeetCode 450: Delete Node in a BST
·1 分鐘
LeetCode Medium Tree Binary-Search-Tree Binary-Tree
LeetCode 450 解題筆記:找到節點後分三種情況:沒有小孩、一個小孩直接接上,兩個小孩用右子樹最小值替換再刪掉它
LeetCode 1372: Longest ZigZag Path in a Binary Tree
·1 分鐘
LeetCode Medium Dynamic-Programming Tree Depth-First-Search Binary-Tree Dp-on-Trees
LeetCode 1372 解題筆記:每個節點回傳兩個值:從這裡先往左、先往右的最長 zigzag;往左走接的是左小孩「先往右」的值