99 恢复二叉树-中等
题目:
给你二叉搜索树的根节点 root
,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。
分析:
二叉树的中序遍历肯定为递增序列,所以迭代的方式遍历,根据当前节点与前继节点的大小关系来判断是否被交换过,并记录。
在递增序列中交换两个值,那么第一次打破递增关系时,一定是前驱节点大于当前节点,前驱节点为被换过的。
第二次打破递增关系时,同样前驱节点大于当前节点,但是当前节点是被换过的。
原始序列:1, 2, 3, 4, 5, 6, 7
交换后的序列:1, 2, 6, 4, 5, 3, 7
第一次为[6,4], 6为置换过的
第二次为[5,3], 3为置换过的
下面看具体算法:
// date 2023/10/22
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func recoverTree(root *TreeNode) {
stack := make([]*TreeNode, 0, 16)
// x, y 记录被交换的两个节点
// pre 记录前驱节点,通过判断当前节点与前驱节点的关系
// 找到两个被错误交换的节点,然后进行交换
var x, y, pre *TreeNode
for root != nil || len(stack) != 0 {
for root != nil {
stack = append(stack, root)
root = root.Left
}
cur := stack[len(stack)-1]
stack = stack[:len(stack)-1]
if pre != nil && cur.Val < pre.Val {
y = cur
if x == nil {
x = pre
} else {
break
}
}
pre = cur
root = cur.Right
}
x.Val, y.Val = y.Val, x.Val
}
最后更新于