leetcode刷題筆記九十九題 恢復二叉搜尋樹
阿新 • • 發佈:2020-08-01
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 } }