[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?

给一棵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);
	}
};



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值