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;
}

最新文章

  1. format not a string literal and no format arguments
  2. Unity加载模块深度解析(网格篇)
  3. Mac OX上安装MongoDb
  4. eclipse部署Tomcat6 : The server does not support version 3.0 of the JEE Web module specification
  5. ASM中的别名
  6. ubuntu恢复rm -rf误删文件
  7. java使用json抛出org.apache.commons.lang.exception.NestableRuntimeException解决方案
  8. http://msh.baidu.com/UTWpR6wY4722
  9. js,jQuery数组常用操作小结
  10. Asp.net的对Excel文档的导入导出操作
  11. SQL 语句优化—— (二) 索引的利用
  12. python 基础学习3-函数
  13. struts体系结构
  14. Android Studio和eclipse混淆打包总结
  15. Git系列②之部署企业级开源仓库gitlab服务器
  16. Zookeeper-Watcher机制与异步调用原理
  17. Python关键字及其用法
  18. opencv 替换图像中的一部分
  19. 自动化运维工具 SaltStack 搭建
  20. gvim配置文件

热门文章

  1. selenium—八种定位方法
  2. TopShelf框架创建Windows服务作为Remoting的宿主案例:
  3. Git学习(四)——分支管理
  4. STM32 使用 FreeRTOS过程记录
  5. 常用的PHP框架
  6. ajaxFileUpload 异步上传数据
  7. alphaBlend
  8. SQL 查询性能优化----解决书签查找
  9. NGUI 按钮点击音效统一管理开启与关闭
  10. python-mysqldb安装