您的位置:首页 > 其它

Recover Binary Search Tree

2014-11-26 10:50 316 查看
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}"
.

这道题是要求恢复一颗有两个元素调换错了的二叉查找树。一开始拿到可能会觉得比较复杂,其实观察出规律了就比较简单。主要还是利用二叉查找树的主要性质,就是中序遍历是有序的性质。那么如果其中有元素被调换了,意味着中序遍历中必然出现违背有序的情况。那么会出现几次呢?有两种情况,如果是中序遍历相邻的两个元素被调换了,很容易想到就只需会出现一次违反情况,只需要把这个两个节点记录下来最后调换值就可以;如果是不相邻的两个元素被调换了,举个例子很容易可以发现,会发生两次逆序的情况,那么这时候需要调换的元素应该是第一次逆序前面的元素,和第二次逆序后面的元素。比如1234567,1和5调换了,会得到5234167,逆序发生在52和41,我们需要把4和1调过来,那么就是52的第一个元素,41的第二个元素调换即可。
搞清楚了规律就容易实现了,中序遍历寻找逆序情况,调换的第一个元素,永远是第一个逆序的第一个元素,而调换的第二个元素如果只有一次逆序,则是那一次的后一个,如果有两次逆序则是第二次的后一个。算法只需要一次中序遍历,所以时间复杂度是O(n),空间是栈大小O(logn)。
C++代码如下:

#include<iostream>
#include<new>
using namespace std;

//Definition for binary tree
struct TreeNode
{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

class Solution
{
public:
TreeNode *first=NULL;
TreeNode *second=NULL;
TreeNode *pre=NULL;
void recoverTree(TreeNode *root)
{
recoverInorder(root);
swap(first->val,second->val);
}
void recoverInorder(TreeNode *root)
{
if(root)
{
recoverInorder(root->left);
if(pre&&pre->val>root->val)
{
if(first==NULL)
{
first=pre;
second=root;
}
else
second=root;
}
pre=root;
recoverInorder(root->right);
}
}
void createTree(TreeNode *&root)
{
int arr[10]= {5,9,7,8,6,10,4,2,1,3};
int i;
for(i=0; i<10; i++)
insert(root,arr[i]);
}
void insert(TreeNode *&root,int key)
{
TreeNode *tmp=new TreeNode(key);
if(root==NULL)
{
root=tmp;
}
else if(key<root->val)
insert(root->left,key);
else
insert(root->right,key);
}
void inorder(TreeNode *root)
{
if(root)
{
inorder(root->left);
cout<<root->val<<" ";
inorder(root->right);
}
}
};

int main()
{
Solution s;
TreeNode *root=NULL;
s.createTree(root);
s.inorder(root);
cout<<endl;
swap(root->left->val,root->right->val);
s.inorder(root);
cout<<endl;
s.recoverTree(root);
s.inorder(root);
}


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: