[Leetcode] Recover binary search tree 恢复二叉搜索树

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Note: 
A solution using O(n ) space is pretty straight forward. Could you devise a constant space solution?

 

confused what"{1,#,2,3}"means? > read more on how binary tree is serialized on OJ.


OJ's Binary Tree Serialization:

The serialization of a binary tree follows a level order traversal, where '#' signifies a path terminator where no node exists below.

Here's an example:

   1
  / \
 2   3
    /
   4
    \
     5
The above binary tree is serialized as"{1,2,3,#,#,4,#,#,5}".
 
最简单的办法应该是,中序遍历二叉树,将各个结点的值存储在一维向量中,然后进行一次赋值操作。这种方法对任意个数的节点错乱都实用。
 详情见Grangyang的博客
 1 /**
 2  * Definition for binary tree
 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     {
14         vector<TreeNode *> treeNode;
15         vector<int> nodeVal;
16         inoder(root,treeNode,nodeVal);
17         sort(nodeVal.begin(),nodeVal.end());
18         for(int i=0;i<treeNode.size();++i)
19             treeNode[i]->val=nodeVal[i];
20     }
21 
22     void inoder(TreeNode *root,vector<TreeNode *> &treeNode,vector<int> &nodeVal)
23     {
24         if(root==NULL)  return;
25         inoder(root->left,treeNode,nodeVal);
26         treeNode.push_back(root);
27         nodeVal.push_back(root->val);
28         inoder(root->right,treeNode,nodeVal);
29     }
30 };

 方法二:

用三个指针,w1,w2分别指向第一、二个错误的地方。pre指向当前结点中序遍历中的前一个结点。因有两个结点交换了,所以二叉树的中序遍历中会出现违背有序的情况,一、即中序遍历中相邻的结点被交换,则违背有序的情况出现一次,如132456;二、中序遍历中不相邻的两个结点的值被交换,则出现两次违背有序情况,如153426.针对情况1,pre=3,w1=pre即为3,w2=root,即为2,在后续的遍历中没有违背有序的情况,所以交换w1和w2即可;针对情况2,找到第一个错误点后,w1 !=NULL了,所以,第二个错误点w2=root,第一逆序的前结点,第二逆序的后结点,交换两者即可。

 1 /**
 2  * Definition for binary tree
 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 *w1,*w2,*pre;
13     void recoverTree(TreeNode *root) 
14     {
15         if(root==NULL)  return;
16         w1=w2=pre=NULL;
17         find(root);
18         swap(w1->val,w2->val);
19     }
20     void find(TreeNode *root)
21     {
22         if(root==NULL)  return;
23         find(root->left);
24         if(pre&&pre->val > root->val)
25         {
26             if(w1==NULL)    //情况1
27             {
28                 w1=pre;
29                 w2=root;
30             }
31             else            //情况2
32                 w2=root;
33         }
34         pre=root;
35         find(root->right);
36     }
37 };

 

方法三

层次遍历中的Mirror方法,修改部分得到。真正的O(1)。

// Now O(1) space complexity
class Solution {
public:
    void recoverTree(TreeNode *root) {
        TreeNode *first = NULL, *second = NULL, *parent = NULL;
        TreeNode *cur, *pre;
        cur = root;
        while (cur) {
            if (!cur->left) {
                if (parent && parent->val > cur->val) {
                    if (!first) first = parent;
                    second = cur;
                }
                parent = cur;
                cur = cur->right;
            } else {
                pre = cur->left;
                while (pre->right && pre->right != cur) pre = pre->right;
                if (!pre->right) {
                    pre->right = cur;
                    cur = cur->left;
                } else {
                    pre->right = NULL;
                    if (parent->val > cur->val) {
                        if (!first) first = parent;
                        second = cur;
                    }
                    parent = cur;
                    cur = cur->right;
                }
            }
        }
        if (first && second) swap(first->val, second->val);
    }
};

 

posted @ 2017-06-13 21:39  王大咩的图书馆  阅读(299)  评论(0编辑  收藏  举报