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
}
}