题目描述:
二叉搜索树中的两个节点被错误地交换。
请在不改变其结构的情况下,恢复这棵树题目
思路:
抓住:只有两个节点被错误地交换这句话,我们需要找到这两个节点
第一种情况:左右各有一个非法节点,直接交换
第二种情况:左右某一边又一个,与根节点交换
如何交换
交换的本质是:从二叉搜索树的性质出发,左子树<根部<右子树;
例如:1,2,8,4,5,3;可以利用中序遍历找出第一对错位(不满足升序)的节点(8,4),再找到第二组不满足升序的节点(5,3),将节点8与节点3的数值交换
思路参考:思路讲解
代码:
class Solution {
static TreeNode prev;
static TreeNode sn,fn; //first bad node, second bad node
public void recoverTree(TreeNode root) {
prev=sn=fn=null;
helper(root);
int temp=fn.val;
fn.val=sn.val;
sn.val=temp;
}
public void helper(TreeNode root)
{
if(root==null)
{
return;
}
helper(root.left);
if(prev!=null && prev.val>=root.val) //不满足升序的节点对
{
if(sn==null)
{
fn=prev;
}
sn=root;
}
prev=root;
helper(root.right);
}
}
该方法用了递归栈,并不是真正的O(1),如果要求真正的O(1)空间,可以用moriss遍历