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)空间的话可以直接中序遍历来找问题节点。

如果是O(1)空间的话,基本上就只能是原地操作了。

这里介绍一个Morris Inorder Traversal。可以实现:

1. 如果当前节点有左子树,那么找到左子树的最右节点并把它右指针指向当前节点。当前节点转移到其左节点。

2. 如果左子树的最右节点已经指向了当前节点(之前已经遍历过左子树),那么还原最右节点的右指针为null, 输出当前节点,当前节点转移到其右节点。

3. 如果当前节点没有左子树,那么直接输出当前节点并将其转移到右节点。

写成代码如下:

     public void recoverTree(TreeNode root) {
TreeNode cur = root;
while(cur!=null) {
if(cur.left!=null) {
TreeNode temp = cur.left;
while(temp.right!=null && temp.right!=cur)
temp = temp.right;
if(temp.right==null) {
temp.right = cur;
cur = cur.left;
}
else {
temp.right=null;
//print
cur=cur.right;
}
}
else {
//print
cur=cur.right
}
}
}
}

结合这道题,只需要在print的地方添加代码即可。

只存在一处错误,遍历时可能出现两种情况:

1. 发现一次原先节点值比当前节点值大,例如:(1, 4, 3, 7, 9)这时只有对调这两个节点值即可。

2. 发现两次原先节点值比当前节点值大,例如: (1, 9, 4, 5, 3, 10)这时需要对调第一次的原先节点值和第二次的当前节点值。

使用两个TreeNode wrong1, wrong2记录这两个错误节点,如果是第一次发现原先节点比当前节点值大的错误,则wrong1置为原先节点,wrong2置为当前节点。如果又发现一次,则只更改wrong2.

注意原先节点pre和当前节点cur的关系,只有cur即将挪向右节点之前才将pre置为cur. (因为cur挪向左节点是第一次遍历左子树,仅仅用来连接,第二次遍历才输出)

完整代码如下:

     public void recoverTree(TreeNode root) {
TreeNode cur = root;
TreeNode pre = null;
TreeNode wrong1 = null;
TreeNode wrong2 = null;
while(cur!=null) {
if(cur.left!=null) {
TreeNode temp = cur.left;
while(temp.right!=null && temp.right!=cur)
temp = temp.right;
if(temp.right==null) {
temp.right = cur;
cur = cur.left;
}
else {
temp.right=null;
//print
if(pre!=null && pre.val>cur.val) {
if(wrong1==null)
wrong1=pre;
wrong2 = cur;
}
pre = cur;
cur=cur.right;
}
}
else {
//print
if(pre!=null && pre.val>cur.val) {
if(wrong1==null)
wrong1=pre;
wrong2 = cur;
}
pre = cur;
cur=cur.right;
}
}
int t = wrong1.val;
wrong1.val = wrong2.val;
wrong2.val = t;
}

[Leetcode][JAVA] Recover Binary Search Tree (Morris Inorder Traversal)的更多相关文章

  1. [LeetCode] 99. Recover Binary Search Tree(复原BST) ☆☆☆☆☆

    Recover Binary Search Tree leetcode java https://leetcode.com/problems/recover-binary-search-tree/di ...

  2. 【leetcode】Recover Binary Search Tree

    Recover Binary Search Tree Two elements of a binary search tree (BST) are swapped by mistake. Recove ...

  3. leetcode 99 Recover Binary Search Tree ----- java

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  4. Java for LeetCode 099 Recover Binary Search Tree

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  5. [LeetCode] 99. Recover Binary Search Tree 复原二叉搜索树

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  6. leetcode@ [173] Binary Search Tree Iterator (InOrder traversal)

    https://leetcode.com/problems/binary-search-tree-iterator/ Implement an iterator over a binary searc ...

  7. [leetcode]99. Recover Binary Search Tree恢复二叉搜索树

    Two elements of a binary search tree (BST) are swapped by mistake. Recover the tree without changing ...

  8. LeetCode 1008. Construct Binary Search Tree from Preorder Traversal

    原题链接在这里:https://leetcode.com/problems/construct-binary-search-tree-from-preorder-traversal/ 题目: Retu ...

  9. 第五周 Leetcode 99. Recover Binary Search Tree (HARD)

    Leetcode99 给定一个 二叉搜索树,其中两个节点被交换,写一个程序恢复这颗BST. 只想到了时间复杂度O(n)空间复杂度O(h) h为树高的解法,还没想到空间O(1)的解法. 交换的情况只有两 ...

随机推荐

  1. Chain Of Responsibility(职责连)-对象行为型模式

    1.意图 使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 2.动机 给多个对象处理一个请求的机会,从而 ...

  2. Xcode - 知道.001

    1.在xcode7以后,一定要有根视图,否则会报错,程序崩溃,

  3. AD账号创建日期、最近一次登录时间、最近一次重置密码时间查询

    一:查询此AD域内所有用户的创建日期 Get-ADuser  -filter * -Properties * | Select-Object Name,SID, Created,PasswordLas ...

  4. Objective-C 变量和基本的数据类型

    转自:http://blog.csdn.net/mengxiangyue/article/details/11369679 OC中有如下基本数据类型: int:声明整型变量 double:声明双精度变 ...

  5. SQL 统计整个服务器上各个数据库占用的空间

    create procedure [dbo].[P__SpaceUsedView]asbegin if not exists (select 0 from tempdb..sysobjects whe ...

  6. PHP数组合并 array_merge 与 + 的差异

    在PHP数组合并出过几次问题都没记住,写下来加强一点记忆 PHP数组在合并时,使用 array_merge 与 + 的差异: 1.array_merge(array $array1 [, array  ...

  7. Java String,StringBuffer和StringBuilder的区别

    [可变与不可变] String是字符串常量,不可变. StringBuffer和StringBuilder是字符串变量,可变. [执行速度方面] StringBuilder > StringBu ...

  8. Hibernate缓存之Aop+cache

    在上一篇涉及到查询缓存的功能时除了需要在配置文件中开启缓存外,还需要在业务代码中显示调用setCacheable(boolean)才可以打开查询缓存的功能,这样做,无疑是破坏了封装性,所以就诞生了利用 ...

  9. 【转载】最完美解决Nginx部署ThinkPHP项目的办法

    网上通用解决方法的配置如下: server { ... location / { index index.htm index.html index.php; #访问路径的文件不存在则重写URL转交给T ...

  10. 大前端学习笔记整理【五】rem与px换算的计算方式

    前言 这段时间的小项目中算是真正意义上使用了rem来进行移动端的页面布局,项目结束了我反思了一下之前的对于rem的使用...原来我以前对rem用法完全是在搞笑啊!!结合这次这个小项目,我觉得我也有必要 ...