99.恢复二叉搜索树

68 阅读1分钟

题目:
给你二叉搜索树的根节点 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
	}
	
}