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
    }
}
posted @ 2020-08-01 16:22  ganshuoos  阅读(148)  评论(0编辑  收藏  举报