leetcode - Recover Binary Search Tree

题目: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?

 

这道题的意思是本来有一颗BST,但是不小心把其中两个节点互换了,现在需要把这两个节点换回来,或者交换这两个节点的值也行,关键在于找到这两个互换节点

个人思路:

1、创建一个vector<TreeNode *> A,保存中序遍历的所有节点,由于原BST有两个节点互换了,那么该中序遍历的结果并不是递增的

2、再创建一个vector<TreeNode *> B,并用A的元素初始化B,然后为B排序,此时的B是递增顺序的(也即对调了互换节点的指针),遍历比较这两个vector的元素,当发现A的元素不等于B的元素时,表明两个不相等的元素就是那两个互换节点,找到这两个互换节点后,交换它俩的值即可

代码:

 1 #include <stddef.h>
 2 #include <vector>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 /*
 7 struct TreeNode
 8 {
 9     int val;
10     TreeNode *left;
11     TreeNode *right;
12     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
13 };
14 */
15 class Solution
16 {
17 public:
18     void recoverTree(TreeNode *root)
19     {
20         vector<TreeNode *> inorderRaw;
21         inorder(root, inorderRaw);
22         vector<TreeNode *> inorderSorted(inorderRaw);
23         sort(inorderSorted.begin(), inorderSorted.end(), Solution::cmp);
24         vector<TreeNode *>::iterator raw = inorderRaw.begin();
25         vector<TreeNode *>::iterator sorted = inorderSorted.begin();
26 
27         while (true)
28         {
29             if ((*raw)->val != (*sorted)->val)
30             {
31                 break;
32             }
33             ++raw;
34             ++sorted;
35         }
36         int tmp = (*raw)->val;
37         (*raw)->val = (*sorted)->val;
38         (*sorted)->val = tmp;
39     }
40     static bool cmp(const TreeNode *first, const TreeNode *second)
41     {
42         return first->val <= second->val;
43     }
44 private:
45     void inorder(TreeNode *root, vector<TreeNode *> &inorderRaw)
46     {
47         if (!root)
48         {
49             return;
50         }
51         inorder(root->left, inorderRaw);
52         inorderRaw.push_back(root);
53         inorder(root->right, inorderRaw);
54     }
55 };
56 /*
57 int main()
58 {
59     return 0;
60 }
61 */
View Code

 

题目要求仅使用常数空间,上面的算法不和要求,上网看了几篇文章,找到了符合题意的算法(一开始我也是这么想的,但后来想岔了),链接:http://blog.163.com/ya_mzy/blog/static/19959325520137153340725/

思路:

1、这里我们先举个例子来说明,比如一个正常的BST中序遍历应该是递增的,如1234567,现在互换了两个节点3和6,变成1264537

2、那么,有什么特点呢?当中序遍历时,会有一个节点比后一个节点大,一个节点比前一个节点小,我们就要找到这两个节点,通过预设一个pre指针用于记录中序遍历的前一个节点即可,当这两个互换的节点相邻时,如1243567,仅会有一次当前节点小于前一节点的情况(一般会出现两次,第一次是前一节点,第二次是当前节点),这时这两个节点便是互换节点

代码:

 1 #include <stddef.h>
 2 
 3 struct TreeNode
 4 {
 5     int val;
 6     TreeNode *left;
 7     TreeNode *right;
 8     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 9 };
10 
11 class Solution
12 {
13 public:
14     void recoverTree(TreeNode *root)
15     {
16         TreeNode *swappedElement1 = NULL;
17         TreeNode *swappedElement2 = NULL;
18         TreeNode *pre = NULL;
19 
20         findSwappedElements(root, pre, swappedElement1, swappedElement2);
21 
22         int tmp = swappedElement1->val;
23         swappedElement1->val = swappedElement2->val;
24         swappedElement2->val = tmp;
25     }
26 private:
27     void findSwappedElements(TreeNode *root, TreeNode *&pre, TreeNode *&swappedElement1, TreeNode *&swappedElement2)
28     {
29         if (!root)
30         {
31             return;
32         }
33 
34         findSwappedElements(root->left, pre, swappedElement1, swappedElement2);
35 
36         if (pre && root->val < pre->val)
37         {
38             if (!swappedElement1)
39             {
40                 swappedElement1 = pre;
41                 swappedElement2 = root;
42             }
43             else
44             {
45                 swappedElement2 = root;
46             }
47         }
48 
49         pre = root;
50 
51         findSwappedElements(root->right, pre, swappedElement1, swappedElement2);
52     }
53 };
54 
55 int main()
56 {
57     return 0;
58 }
View Code

 

posted on 2014-06-23 16:57  laihaiteng  阅读(174)  评论(0编辑  收藏  举报

导航