题目:
给你二叉搜索树的根节点 root ,该树中的 恰好 两个节点的值被错误地交换。请在不改变其结构的情况下,恢复这棵树 。
算法:
归根到底还是利用BST的特性,left < root < right
1、可以表示为中序遍历是个升序。
可以把中序遍历的结果保存再数组中,找到两个下降处。第一个下降处的高点,和第二个下降处的低点就是我们要找的两个点
方法一:中序遍历结果保存到数组中
func recoverTree(root *TreeNode) {
array := make([]*TreeNode, 0)
iterBST(root, &array)
var node1, node2 *TreeNode
for i := 1; i < len(array); i ++ {
if array[i - 1].Val > array[i].Val {
node1 = array[i]
if node2 == nil {
node2 = array[i - 1]
}
}
}
if node1 != nil && node2 != nil {
node1.Val, node2.Val = node2.Val, node1.Val
}
}
func iterBST(root *TreeNode, array *[]*TreeNode) {
if root == nil {
return
}
iterBST(root.Left, array)
*array = append(*array, root)
iterBST(root.Right, array)
}
方法二:中序遍历,迭代保存父节点的value 如果不用匿名函数,需要使用指向指针的指针
func recoverTree(root *TreeNode) {
var node1, node2 *TreeNode
preNode := &TreeNode{Val:math.MinInt64}
var iterBST func(*TreeNode)
iterBST = func(root *TreeNode) {
if root == nil {
return
}
iterBST(root.Left)
if root.Val < preNode.Val {
fmt.Println(preNode.Val, root.Val)
node1 = root
if node2 == nil {
node2 = preNode
}
}
preNode = root
iterBST(root.Right)
}
iterBST(root)
fmt.Println(node1.Val, node2.Val)
if node1 != nil && node2 != nil {
node1.Val, node2.Val = node2.Val, node1.Val
}
}