博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LeetCode-Recover Binary Search Tree
阅读量:4699 次
发布时间:2019-06-09

本文共 2822 字,大约阅读时间需要 9 分钟。

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?

 

confused what "{1,#,2,3}" means? 

 

找个二叉搜索树中出错的两个元素,交换位置来恢复二叉搜索树。同时题目要求只用常数空间复杂度,普通的遍历方式使用了栈或者递归,因此在空间复杂度上不满足要求。这里使用Morris Traversal,简单的说就是充分利用二叉树的叶子节点,使叶子节点的又指针指向在中序遍历中的后继节点。关于Morris Traversal的详细介绍,参考这篇博文。

我们先来实现一个Morris Traversal遍历的代码:

public void morrisTraversal(TreeNode root) {        if(root == null) return;        TreeNode pre = new TreeNode(Integer.MIN_VALUE);while(root != null) {            if(root.left != null) {                TreeNode tmp = root.left;                while(tmp.right!=null && tmp.right!=root)                    tmp = tmp.right;                if(tmp.right == null) {                    tmp.right = root;                    root = root.left;                } else {                    tmp.right = null;                    System.out.println(root.val); //业务逻辑                    root = root.right;                }            } else {                System.out.println(root.val); //业务逻辑                root = root.right;            }        }    }

上述代码使用Morris Traversal实现了二叉树的中序遍历。其中两处System.out.println(root.val)是中序遍历的业务处理部分。在本题中,我们需要找到出错的两处节点,只要修改这两处业务逻辑即可。修改后的代码如下:

public void recoverTree(TreeNode root) {        if(root == null) return;        TreeNode pre = new TreeNode(Integer.MIN_VALUE);        TreeNode error1 = null;        TreeNode error2 = null;        while(root != null) {            if(root.left != null) {                TreeNode tmp = root.left;                while(tmp.right!=null && tmp.right!=root)                    tmp = tmp.right;                if(tmp.right == null) {                    tmp.right = root;                    root = root.left;                } else {                    tmp.right = null;//find error                    if(root.val < pre.val) {                        if(error1 == null) error1 = pre;                        error2 = root;                    }                     pre = root;                                        //System.out.println(root.val);                    root = root.right;                }            } else {                //find error                if(root.val < pre.val) {                    if(error1 == null) error1 = pre;                    error2 = root;                }                 pre = root;                                //System.out.println(root.val);                root = root.right;            }        }                if(error1 != null && error2 != null) {            int tmp = error1.val;            error1.val = error2.val;            error2.val = tmp;        }    }

上述代码中,我们用error1和error2指向两个出错的节点,并在循环结束后将两个节点的内容互换来恢复二叉树。

转载于:https://www.cnblogs.com/linxiong/p/4498780.html

你可能感兴趣的文章
Oracle 组函数count()
查看>>
Session的使用过程中应注意的一个小问题
查看>>
SDK,API,DLL名词解释
查看>>
试探算法
查看>>
jquery.validation.js 使用
查看>>
数据库高级查询
查看>>
C语言实现封装、继承和多态
查看>>
创建文件
查看>>
Nginx 相关介绍
查看>>
leetcode[33]Search in Rotated Sorted Array
查看>>
OpenCV Shi-Tomasi角点检测子
查看>>
eval(PHP 4, PHP 5)
查看>>
readelf用法小记
查看>>
Java中JavaScript unescape与escape函数算法
查看>>
js的基础要点
查看>>
C#/IOS/Android通用加密解密方法
查看>>
Web API 简单示例
查看>>
返璞归真 asp.net mvc (4) - View/ViewEngine
查看>>
ADO.Net对Oracle数据库的操作【转载】
查看>>
Contoso 大学 - 6 – 更新关联数据
查看>>