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?
唉,以前一下就ac的题目。。现在竟然想不出来怎么做,还是没有动手仔细在纸上写写画画
一棵正确的二叉搜索树的中序遍历是一个升序序列,这里就以这个特征为切入点
利用2个临时的节点 wa1和wa2 来记录下错误的节点,然后交换二者的值即可。
这里问题来了,如何找出wa1和wa2?
如果允许使用O(n)的空间,那就直接中序遍历,记录下中序的路径。从前往后找出第一个比后继大的数,从后往前找出第一个比前驱小的,这两个节点就是被swapped by mistake的节点。
如果不允许使用O(n)的空间
那就中序遍历,先找到第一个不对的节点,即,每遍历一个点,就把这个节点赋值给wa1,直到某个节点的值比wa1的值小,则wa1找到了,并且,在这里要将这个比wa1值小的节点记录到wa2中,因为很有可能是相邻的两个节点被swapped by mistake
找第二个节点的时候就是 一直进行中序遍历,如果node的值一直比wa1的值小,那就继续遍历,并且把node赋给wa2,直到某个node的值比wa1大,此时,wa2中保存的节点就是第二个swapped by mistake的节点。
class Solution {
public:
TreeNode* wa1=NULL,*wa2=NULL;
int flag = 0;
void recoverTree(TreeNode *root) {
wa1 = new TreeNode(-100000);
wa2 = new TreeNode(-100000);
view(root);
int tmp = wa1->val;
wa1->val = wa2->val;
wa2->val = tmp;
}
void view(TreeNode* node){
if(node==NULL)
return;
view(node->left);
if(flag==0){
if(node->val<wa1->val){
flag++;
wa2 = node;
}
else
wa1 = node;
}else if(flag==1){
if(node->val<wa1->val)
wa2 = node;
else{
flag++;
return;
}
}else
return;
view(node->right);
}
};
这里要注意,一棵二叉搜索树中有两个节点的值被交换以后,它的中序遍历序列的顺序也是保持一定特征的,即找到第一个逆序对以后,那么较大值肯定是被错误交换的一个,然后就继续中序遍历,直到找到最后一个比先前最大值小的节点,这两个值即是被交换的值。