LeetCode 99. Recover Binary Search Tree

题意:找出“BST”中不符合规律的两个结点。

 

解题思路:

  1. 对于BST,中序遍历就是一个递增序列,因此,只要依赖于中序遍历就能够找到两个有问题的结点,然后交换结点的值就行了。

 

 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     void recoverTree(TreeNode* root) {
13         stack<TreeNode*> s;
14         TreeNode* tmp=root;
15         TreeNode* t1,*t2;  //指示wrong position的结点
16         bool flag=false;   //判断是第一次还是第二次
17         TreeNode* pre=NULL;
18         
19         while(!s.empty() || tmp!=NULL){
20             if(tmp!=NULL){
21                 s.push(tmp);
22                 tmp=tmp->left;
23             }
24             else{
25                 while(!s.empty() && s.top()->right==NULL){   
26                     // 发生错误
27                     if(pre!=NULL && pre->val>s.top()->val){
28                         cout<<"gg"<<endl;
29                         if(flag==false){
30                             t1=pre;
31                             t2=s.top();
32                             flag=true;
33                         }
34                         else{
35                             t2=s.top();
36                         }
37                     }
38                     pre=s.top();
39                     //cout<<pre->val<<endl;
40                     s.pop();
41                 }
42                 if(!s.empty()){
43                     // 发生错误
44                     if(pre!=NULL && pre->val>s.top()->val){
45                         cout<<"gg"<<endl;
46                         if(flag==false){
47                             t1=pre;   
48                             t2=s.top();
49                             flag=true;
50                         }
51                         else{
52                             t2=s.top();
53                         }
54                     }
55                     pre=s.top();
56                     //cout<<pre->val<<endl;
57                     tmp=s.top()->right;
58                     s.pop();
59                 }
60             }
61         }
62         
63         int data=t1->val;
64         t1->val=t2->val;
65         t2->val=data;
66         
67     }
68 };
  • 在这里,我采用的是非递归中序遍历,使用pre记录前驱,tmp记录当前结点。   
  • 其实,这个题就是在建立中序线索二叉树。  https://www.cnblogs.com/yy-1046741080/p/11511263.html
  • 对于中序遍历,弹栈的时候才是中序序列,因此,pre的改变是发生在弹栈的时候,而且需要先进行比较。
  • 在数据中,因为错误可能存在接连两个结点:所以在31行和48行必须处理t2;否则就会漏元素。
 
posted @ 2019-10-04 13:10  B_luePhantom  阅读(99)  评论(0编辑  收藏  举报