题目:
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?
题目的意思是,有一个二叉排序树,其中有两个节点的位置换了,可能是相邻节点也可能是不相邻的节点,在不该变二叉树结构的情况下,恢复该二叉树。空间复杂度为O(n)。
解题思路:
方法一:在不考虑空间复杂度的情况下,申请额外的空间。比如Java的ArrayList<TreeNode> ,中序遍历该二叉树,将每个节点添加到ArrayList<TreeNode> 中,如果二叉排序中的节点位置没有交换,那么它的顺序是从小到大排列。如果有节点位置交换,那么它的顺序一定不是从小到大排列的。从而找到两个节点,只需要交换值即可,不需要交换左右子树的地址值。代码比较简单,就不写了。这种方法可能不符合要求。
方法二:刚开始没有想到,后来参考别人的代码,写下自己的理解吧。想法就是设置三个全局变量,分别为pre,first,second.pre用来存储当前访问节点的前一个节点,first存储第一个错误的节点,second来存储第二个错误的节点。这种方法也是采用中序遍历的方法,所以pre指向节点的值一定小于当前访问节点的值的,(pre.val<root.val),如果(pre.val>root.val)说明pre节点的位置是错误的,所以这时候如果first为空的话,那么用first指向该节点。如果是相邻节点second指向root就可以了。如果不是相邻的节点,还会继续出现pre.val>root.val,因为是中序遍历肯定先找到左子树错误的那个,然后找到根节点,或者右子树的那个节点。但是现在两个节点不相邻,所以肯定在右子树上。pre.val>root.val 。pre为根,root的值是错误的。second指向它就可以了。
代码如下:
TreeNode pre,first,second;
public void recoverTree(TreeNode root) {
if(root==null){
return ;
}
pre=null;
first=null;
second=null;
recoverVisit(root);
if(first==null&&second==null){
int temp=first.val;
first.val=second.val;
second.val=temp;
}
}
public void recoverVisit(TreeNode root){
if(root==null){
return ;
}
recoverVisit(root.left);
if(pre==null){
pre=root;
}else{
if(pre.val>root.val){
if(first==null){
first=pre;
}
second=root;
}
pre=root;
}
recoverVisit(root.left);
}
理解别人算法最简单的方法是,自己构建二叉树按照算法走一遍
方法三,持续更新....