美文网首页
[LeetCode](week13)99. Recover Bi

[LeetCode](week13)99. Recover Bi

作者: jeff98 | 来源:发表于2018-12-12 08:54 被阅读0次

题目

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Example 1:

Input: [1,3,null,null,2]

   1
  /
 3
  \
   2

Output: [3,1,null,null,2]

   3
  /
 1
  \
   2
Example 2:

Input: [3,1,4,null,null,2]

  3
 / \
1   4
   /
  2

Output: [2,1,4,null,null,3]

  2
 / \
1   4
   /
  3

Follow up:

A solution using O(n) space is pretty straight forward. Could you devise a constant space solution?

题解

第一版本

这一个版本超出内存限制了

func recoverTree(root *TreeNode)  {
    if root != nil {
        dfs(root)
    }
    
}

func dfs(root *TreeNode) bool{
    
    // bfs to move nextNode, swap with firstNode(root) and check
    // if succeed, return true and skip
    if root == nil {
        return false;
    }
    var queue []*TreeNode
    queue = append(queue, root)

    

    for len(queue) != 0 {
        
        headNode := queue[0]
        if headNode.Left != nil {queue =  append(queue, headNode.Left) }
        if headNode.Right != nil {queue =  append(queue, headNode.Right)}
        
        headNode.Left, headNode.Right = headNode.Right, headNode.Left
        if check(root) {
            return true
        }
        headNode.Left, headNode.Right = headNode.Right, headNode.Left
    }
    
    // firstNode move to next, pre-order dfs
    var flag bool
    if root.Left != nil{
        flag = dfs(root.Left)
    }
    
    if !flag && root.Right != nil{
        flag = dfs(root.Right)
    }
    
    return flag
} 


func check(root *TreeNode) bool{
    if root == nil {
        return true
    }
    
    checkLeft := (root.Left == nil || root.Left.Val < root.Val) && check(root.Left)
    checkRight := (root.Right == nil || root.Right.Val > root.Val) && check(root.Right)
    
    return (checkLeft && checkRight);
}

第二版本

“冒泡”思路。

func recoverTree2(root *TreeNode)  {
    help(root)
    first.Val, second.Val = second.Val, first.Val
}

func help(root *TreeNode) {
    if root == nil { return }
    help(root.Left)
    if(first == nil && prev.Val >= root.Val){
        first = prev
    }
    if(first != nil && prev.Val >= root.Val){
        second = root
    }
    prev = root
    help(root.Right)
}

令人诧异的是:同一份TestCase在Run和Submit居然有不同的结果!这属于编译器本地错误了,不管它

第三版本

要利用好Go的语言特性,使用channel 进行并发;且仅占O(1)内存空间

func Swap(x, y *TreeNode) {
    x.Val, y.Val = y.Val, x.Val
}

func Inorder(c chan *TreeNode, root *TreeNode) {
    if root == nil {
        return
    }
    Inorder(c, root.Left)
    c <- root
    Inorder(c, root.Right)
}

func recoverTree(root *TreeNode) {
    c := make(chan *TreeNode)
    go func() {
        Inorder(c, root)
        close(c)
    }()

    var first, second *TreeNode
    prev := <-c
    for x := range c {
        if x.Val < prev.Val {
            if first == nil {
                first = prev
            } 
            if first != nil {
                second = x
            }
        }
        prev = x
    }
    Swap(first, second)
}

相关文章

网友评论

      本文标题:[LeetCode](week13)99. Recover Bi

      本文链接:https://www.haomeiwen.com/subject/lvfuhqtx.html