1. 程式人生 > >[leetcode] 99. 恢復二叉搜尋樹

[leetcode] 99. 恢復二叉搜尋樹

99. 恢復二叉搜尋樹

一開始想了好久沒有什麼好思路,去網上搜了一下,原來是中序遍歷。

二叉搜尋樹的中序遍歷是個(遞增)有序數列,利用這個特性,我們可以很巧妙的解決這個題。

先看第二個例子,中序遍歷後是:13245,觀察發現只有一處發生了降序,只在第二位與第三位發生了降序情況,說明這兩個數為異常數,交換3和2的位置重新中序遍歷:12345

第一個例子,中序遍歷是:321,觀察發現有兩處發生了降序,第一到第二位,以及第二到第三位,這種情況下交換第一位與第三位即可

實際上題目中只有兩個節點被交換了,所以降序情況最多也只會出現兩處。所以分兩種情況處理即可。

我們再造個例子,看的更直觀點:

[10 17 15 1 8 12 5]

中序遍歷

1 17 8 10 12 15 5

17與3發生了降序,15與5發生了降序,我們將第一個降序的前一個元素與第二個降序的後一個元素,進行交換即可。

當只有一次降序出現時(可以理解為兩個降序擠到了一塊嘛),降序的前一個元素與降序的後一個元素,進行交換即可。

程式碼

class Solution {
    TreeNode p, q, last;

    void middle(TreeNode root) {
        if (root == null) return;
        middle(root.left);
        if (last != null && last.val > root.val) {
            if (p == null) p = last;
            q = root;
        }
        last = root;
        middle(root.right);
    }

    public void recoverTree(TreeNode root) {
        middle(root);
        int tmp = p.val;
        p.val = q.val;
        q.val = tmp;
    }
}