[leetcode] 99. 恢復二叉搜尋樹
阿新 • • 發佈:2018-11-05
一開始想了好久沒有什麼好思路,去網上搜了一下,原來是中序遍歷。
二叉搜尋樹的中序遍歷是個(遞增)有序數列,利用這個特性,我們可以很巧妙的解決這個題。
先看第二個例子,中序遍歷後是: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; } }