1. 程式人生 > >【leetcode】99.(Hard)Recovery Binary Search Tree

【leetcode】99.(Hard)Recovery Binary Search Tree

解題思路:中序Morris遍歷
搜尋二叉樹就是一棵樹,所有左子樹中的結點都比根節點的值小,所有右子樹中結點的值都比根節點的值大。

這個題的意思是,一個搜尋二叉樹有兩個結點的值被調換了,然後我們要找到這兩個結點,修復這個搜尋二叉樹。

根據題意,只有兩個結點的值是互調的,所以這個壞掉的搜尋二叉樹會有兩個地方在中序遍歷下大小順序是不對的。

例如下面這顆樹有兩個結點被調換了(1和3),本來中序遍歷下來應該是[1-2-3]的順序,但是這顆樹按照中序遍歷排序是[3-2-1],所以有兩個地方[3-2]和[2-1]是不對的,需要調換的結點是是**第一個地方的第一個結點3和第二個地方的第一個結點1。**將這兩個結點調換以後順序就可以變為[1-2-3]了。

在這裡插入圖片描述

題目希望我們使用O(1)的空間大小。一個樹的遍歷方式有前序中序後序、遞迴非遞迴morris遍歷共3*3=9種遍歷方式。這裡使用中序遍歷(二叉搜尋樹一般使用中序遍歷),然後使用morris遍歷。
關於morris遍歷:
https://blog.csdn.net/zuochao_2013/article/details/78538729
https://www.cnblogs.com/AnnieKim/archive/2013/06/15/MorrisTraversal.html


提交程式碼:

/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution { public void recoverTree(TreeNode root) { if(root==null) return; TreeNode swap1=null,swap2=null; TreeNode tmp=null,pre=null,cur=root; while(cur!=null) { if(cur.left==null) { if(pre!=null&&pre.val>cur.val) { if(swap1==null) { swap1=pre;swap2=cur;
}else { swap2=cur; //swapTreeNode(swap1,swap2); } } pre=cur;cur=cur.right; }else { // left is not null tmp=cur.left; while(tmp.right!=null&&tmp.right!=cur) tmp=tmp.right; if(tmp.right==null) { tmp.right=cur; cur=cur.left; }else { tmp.right=null; if(pre!=null&&pre.val>cur.val) { if(swap1==null) { swap1=pre;swap2=cur; }else { swap2=cur; //swapTreeNode(swap1,swap2); } } pre=cur; cur=cur.right; } } } swapTreeNode(swap1,swap2); } public void swapTreeNode(TreeNode swap1,TreeNode swap2) { int tmp=swap1.val; swap1.val=swap2.val; swap2.val=tmp; } }

執行結果:
在這裡插入圖片描述