1. 程式人生 > >Leetcode 99.恢復二叉搜尋樹

Leetcode 99.恢復二叉搜尋樹

恢復二叉搜尋樹

二叉搜尋樹中的兩個節點被錯誤地交換。

請在不改變其結構的情況下,恢復這棵樹。

示例 1:

輸入: [1,3,null,null,2]

 

  1

  /

 3

  \

  2

 

輸出: [3,1,null,null,2]

 

  3

  /

 1

  \

  2

示例 2:

輸入: [3,1,4,null,null,2]

 

3

/ \

1 4

  /

  2

 

輸出: [2,1,4,null,null,3]

 

2

/ \

1 4

  /

 3

進階:

  • 使用 O(n) 空間複雜度的解法很容易實現。
  • 你能想出一個只使用常數空間的解決方案嗎?

 

中序遍歷二叉樹,出現的節點的值會升序排序,如果有兩個節點位置錯了,那肯定會出現降序。設定一個pre節點指標,記錄當前節點中序遍歷時的前節點,如果當前節點小於pre節點的值,說明需要調整次序。如果在中序遍歷時節點值出現了兩次降序,第一個錯誤的節點為第一次降序時較大的節點,第二個錯誤節點為第二次降序時較小的節點。比如,原來的搜尋二叉樹在中序遍歷的節點值依次為{1,2,3,4,5},如果因為兩個節點位置錯了而出現{1,5,3,4,2},第一次降序為5->3,所以第一個錯誤節點為5,第二次降序為4->2,所以第二個錯誤節點為2,將5和2換過來就可以恢復。

 

 1 /**
 2  * Definition for a binary tree node.
 3  * struct TreeNode {
 4  *     int val;
 5  *     TreeNode *left;
 6  *     TreeNode *right;
 7  *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 8  * };
 9  */
10 class Solution{
11 public:
12     TreeNode* mistake1;
13     TreeNode* mistake2;
14 TreeNode* pre=NULL; 15 16 void recoverTree(TreeNode* root){ 17 recursive_traversal(root); 18 if(mistake1!=NULL && mistake2!=NULL){ 19 swap(mistake1->val,mistake2->val); 20 } 21 } 22 23 //遞迴中序遍歷二叉樹 24 void recursive_traversal(TreeNode* root){ 25 if(root==NULL) 26 return; 27 if(root->left!=NULL){ 28 recursive_traversal(root->left); 29 } 30 if(pre!=NULL && pre->val>root->val){ 31 if(mistake1==NULL){ 32 mistake1=pre; 33 mistake2=root; 34 }else{ 35 mistake2=root; 36 } 37 } 38 pre=root; 39 if(root->right!=NULL){ 40 recursive_traversal(root->right); 41 } 42 } 43 };