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 */
题目要求仅使用常数空间,上面的算法不和要求,上网看了几篇文章,找到了符合题意的算法(一开始我也是这么想的,但后来想岔了),链接: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 }
posted on 2014-06-23 16:57 laihaiteng 阅读(174) 评论(0) 编辑 收藏 举报