其实应该想到,中序遍历正常的搜索二叉树,得到的是一个有序的二叉树,所以应当利用这一点。第一个错误节点为第一次降序较大的值,第二次错误节点为第二次降序较小的结点。
题目如下:
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树。
示例 1:
输入: [1,3,null,null,2] 1 / 3 \ 2 输出: [3,1,null,null,2] 3 / 1 \ 2
我的笨解决办法:32ms,需要多次的调整
package test;
public class LC99Try1
{
public void recoverTree(TreeNode root)
{
int ret=getPass(root,null,null);
//时间浪费到多次调整上边了
while(ret!=1){
ret=getPass(root,null,null);
}
}
public int getPass(TreeNode root,TreeNode leftNode,TreeNode rightNode){
if(root==null){
return 1;
}
if(leftNode!=null){
if(root.valrightNode.val){
int temp=root.val;
root.val=rightNode.val;
rightNode.val=temp;
return -1;
}
}
int leftRet=getPass(root.left,leftNode,root);
if(leftRet==-1){
return -1;
}
int rightRet=getPass(root.right,root,rightNode);
if(rightRet==-1){
return -1;
}
return 1;
}
}
第二种解决办法:中序,29ms
package test;
public class LC99Try2
{
TreeNode firstNode=null;
TreeNode secondNode=null;
TreeNode preNode= new TreeNode(Integer.MIN_VALUE);
public void recoverTree(TreeNode root)
{
getPass(root);
int temp=firstNode.val;
firstNode.val=secondNode.val;
secondNode.val=temp;
}
//中序遍历
public void getPass(TreeNode root){
if(root==null){
return;
}
getPass(root.left);
if(firstNode==null && preNode.val>=root.val){
firstNode=preNode;
}
//这一步就用的很巧,【2,1】
if(firstNode !=null && preNode.val>=root.val){
secondNode=root;
}
preNode=root;
getPass(root.right);
}
}
哈哈