码迷,mamicode.com
首页 > 其他好文 > 详细

[Leetcode]Recover Binary Search Tree

时间:2014-12-01 22:34:27      阅读:309      评论:0      收藏:0      [点我收藏+]

标签:leetcode   bst   

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,其中有两个元素被调换了位置,让我们那这棵树恢复。

根据BST的性质(上一篇博客中已提到过),把BST中序遍历一下可以得到一个升序排列的序列。那么这道题最简单的方法就是中序遍历,把遍历结果存起来,比较得出位置错误的元素,然后还原就可以,这样空间复杂度是O(n)。但是题目中要求用O(1)的空间,又应该如何解决呢?

想想上面中序遍历的过程,我们要把每个元素存下来,最后做比较。比较的过程,就是每个元素和它的前一个作比较,确保这个元素比上一个小,以此维护BST的性质。如此想来,我们遍历过程中只要保存两个元素(当前元素和上一元素)就可以维护BST的性质了。

因此,我们的解法还是用中序遍历,只不过每次要向下传递当前元素的指针作为上一元素,供下次迭代使用。

同时,我们还需要保存出错节点的指针,用来最后恢复这棵BST。这里我用了一个pair类型来保存最后要交换元素的两个指针。

到这里很多同学认为这个问题已经结束了,其实不然。这里被交换的元素还可能有两种情况:相邻元素或者不相邻元素。

如果是不相邻元素,肯定会出现两次当前节点的值比上一节点的值大的情况,两个指针分别保存就可以了。但万一是相邻元素的话,那么其实被交换的两个元素就是pre指针和当前指针的元素,那么就要保存这两个指针。所以第一次出现不符合BST性质的元素时,pair类型mistakes就要记录这两个指针。如果后面出现第二次,就再更新mistakes.second就可以了。到这里,这道题才算结束了。

PS:这道题想了好久......

class Solution {
public:
	void recoverTree(TreeNode *root) {
		pair<TreeNode *, TreeNode *> mistakes;
		TreeNode *pre = NULL;
		locateMistake(root, mistakes, pre);
		if (NULL != mistakes.first && NULL != mistakes.second){
			int tmp = mistakes.first->val;
			mistakes.first->val = mistakes.second->val;
			mistakes.second->val = tmp;
		}
	}
	void locateMistake(TreeNode *root, pair<TreeNode *, TreeNode *> &mistakes, TreeNode *&pre){
		if (NULL == root) return;
		if (root->left) locateMistake(root->left, mistakes, pre);
		if (pre != NULL && root->val < pre->val){
			if (NULL == mistakes.first){
				mistakes.first = pre;
				mistakes.second = root;
			}
			else{
				mistakes.second = root;
			}
		}
		pre = root;
		if (root->right) locateMistake(root->right, mistakes, pre);
	}
};



[Leetcode]Recover Binary Search Tree

标签:leetcode   bst   

原文地址:http://blog.csdn.net/cr_peace/article/details/41652179

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!