zoukankan      html  css  js  c++  java
  • leetcode刷题笔记九十九题 恢复二叉搜索树

    leetcode刷题笔记九十九题 恢复二叉搜索树

    源地址:99. 恢复二叉搜索树

    问题描述:

    二叉搜索树中的两个节点被错误地交换。

    请在不改变其结构的情况下,恢复这棵树。

    示例 1:

    输入: [1,3,null,null,2]

    1
    /
    3

    2

    输出: [3,1,null,null,2]

    3
    /
    1

    2
    示例 2:

    输入: [3,1,4,null,null,2]

    3
    /
    1 4
    /
    2

    输出: [2,1,4,null,null,3]

    2
    /
    1 4
    /
    3
    进阶:

    使用 O(n) 空间复杂度的解法很容易实现。
    你能想出一个只使用常数空间的解决方案吗?

    /**
    处理本题主要采用三种方法,递归,非递归,莫里斯排序
    由于本题中提到了二叉搜索树及两个结点的数值出现颠倒,很容易联想到之前对二叉搜索树中常见的中序遍历,结点有序。在遍历过程中,易发现两组prev值大于cur值现象,前一组的prev 和 后一组的cur即为需要调换的位置。
    */
    //递归方法
    /**
     * Definition for a binary tree node.
     * class TreeNode(_value: Int = 0, _left: TreeNode = null, _right: TreeNode = null) {
     *   var value: Int = _value
     *   var left: TreeNode = _left
     *   var right: TreeNode = _right
     * }
     */
    object Solution {
        def recoverTree(root: TreeNode): Unit = {
            var x: TreeNode = null
            var y: TreeNode = null
            var prev: TreeNode = null
            def helper(root: TreeNode): Unit = {
                if (root == null) return
                //递归左子树
                helper(root.left)
                //出现prev.value > root.value这种情况
                if (prev  != null && prev.value > root.value){
                    y = root
                    //如果x没更新,即第一组情况需要优先更新x
                    //第二组将重新更新y
                    if (x == null) x = prev
                    else return
                }
                prev = root
                //递归右子树
                helper(root.right)
            }
            helper(root)
            val temp = x.value
            x.value = y.value
            y.value = temp
        }
    }
    
    //非递归使用stack进行迭代
    /**
     * Definition for a binary tree node.
     * class TreeNode(_value: Int = 0, _left: TreeNode = null, _right: TreeNode = null) {
     *   var value: Int = _value
     *   var left: TreeNode = _left
     *   var right: TreeNode = _right
     * }
     */
    import scala.collection.mutable.Stack
    object Solution {
        def recoverTree(root: TreeNode): Unit = {
            var x: TreeNode = null
            var y: TreeNode = null
            var prev: TreeNode = null
            var start = root
            val stack = new Stack[TreeNode]()
    		//栈不为空且当前结点不为空,依次放入左子树结点
            while (stack.size > 0 || start != null){
                while (start != null){
                    stack.push(start)
                    start = start.left
                }
                //到达最左侧,弹出
                start = stack.pop
                //如果出现颠倒情况处理
                if (prev != null && prev.value > start.value){
                    y = start
                    if (x == null)  x = prev
                }
                //尝试遍历退出结点的右子树
                prev = start 
                start = start.right
            }
    
            val temp = x.value
            x.value = y.value
            y.value = temp
        }
    }
    
    //莫里斯遍历
    //莫里斯遍历之前在中序遍历时已经看到,这里主要针对几类情况进行处理
    //1.是否有左子树
    //2.没有左子树右节点与根节点链接,加链;否则,断链
    /**
     * Definition for a binary tree node.
     * class TreeNode(_value: Int = 0, _left: TreeNode = null, _right: TreeNode = null) {
     *   var value: Int = _value
     *   var left: TreeNode = _left
     *   var right: TreeNode = _right
     * }
     */
    object Solution {
        def recoverTree(root: TreeNode): Unit = {
            var x: TreeNode = null
            var y: TreeNode = null
            var prev: TreeNode = null
            var predecessor: TreeNode = null
            var start = root
            
            while (start != null){
                if (start.left != null){
                    predecessor = start.left
                    while (predecessor.right != null && predecessor.right != start) predecessor = predecessor.right
                    if (predecessor.right == null){
                        predecessor.right = start
                        start = start.left
                    }
                    else{
                        if (prev != null && prev.value > start.value){
                            y = start
                            if(x == null) x = prev
                        }
                        prev = start
                        predecessor.right = null
                        start = start.right
                    }
                }
                else{
                    if (prev != null && prev.value > start.value){
                        y = start
                        if(x == null) x = prev
                    }
                    prev = start
                    start = start.right
                }
            }
            
            val temp = x.value
            x.value = y.value
            y.value = temp
        }
    }
    
  • 相关阅读:
    mycat1.6.6.1读写分离-分库分表-keepalived高可用-mysql主从
    水火一一
    CentOS7.3虚拟机vmware双网卡配置
    GoldenGate的安全配置
    GoldenGate实时投递数据到大数据平台(1)-MongoDB
    GoldenGate实时投递数据到大数据平台(7)– Apache Hbase
    GoldenGate实时投递数据到大数据平台(5)
    GoldenGate实时投递数据到大数据平台(4)- ElasticSearch 2.x
    明史资料010---- (明初功臣表)明朝建国前后功劳最大的一百五十位功臣名单以及他们的简历
    转载oracle ogg--ogg搭建过程中遇到的错误及处理
  • 原文地址:https://www.cnblogs.com/ganshuoos/p/13415136.html
Copyright © 2011-2022 走看看