• 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
        }
    }
    
  • 相关阅读:
    CF1438C Engineer Artem
    Python小程序:向SecureCRT发送命令
    PyInstaller,可将py脚本转换为exe
    在Virtual Box上安装linux系统,启动SSH服务
    Python介绍
    Git使用入门
    字符编码介绍
    适配器模式Adapter、外观模式Facade-- 学习HeadFirst设计模式记录
    复合模式Compound -- 学习HeadFirst设计模式记录
    代理模式Proxy-- 学习HeadFirst设计模式记录
  • 原文地址:https://www.cnblogs.com/ganshuoos/p/13415136.html
Copyright © 2020-2023  润新知