November 21, 2018
https://leetcode-cn.com/problems/recover-binary-search-tree/
使用语言: Golang
/**
* Definition for a binary tree node.
* type TreeNode struct {
* Val int
* Left *TreeNode
* Right *TreeNode
* }
*/
func recoverTree(root *TreeNode) {
var lastNode *TreeNode
var inorder func(*TreeNode)
var bigger *TreeNode
var smaller *TreeNode
inorder = func (_root *TreeNode) {
if _root == nil {
return
}
inorder(_root.Left)
if bigger == nil && lastNode != nil && _root.Val < lastNode.Val {
bigger = lastNode
}
if lastNode != nil && _root.Val < lastNode.Val {
smaller = _root
}
lastNode = _root
inorder(_root.Right)
}
inorder(root)
bigger.Val, smaller.Val = smaller.Val, bigger.Val
}
首先,你要了解遍历一棵树有哪些方式:https://zh.wikipedia.org/wiki/%E6%A0%91%E7%9A%84%E9%81%8D%E5%8E%86
深度优先遍历 - 前序遍历: F, B, A, D, C, E, G, I, H.
深度优先遍历 - 中序遍历: A, B, C, D, E, F, G, H, I.
深度优先搜索 - 后序遍历: A, C, E, D, B, H, I, G, F.
广度优先遍历 - 层次遍历: F, B, G, A, D, I, C, E, H.
其次你要明白什么是二叉搜索树
结合以上知识点,我们可以得出,按照 左 -> 中 -> 右 的顺序遍历(中序遍历)整棵树,我们能够拿到一个从小到大排列的数组。
那我们要做的事情就简单了: 中序遍历整棵树,记录上个节点的值,与当前节点的值做比较,找到不符合上个节点的值小于当前节点这一条件的节点,就是上面代码中的 bigger
又因为题中承诺只有两个节点被错误的交换了,也就是说,大的数放在了靠前的位置,小的数放在了靠后的位置,即第一个遇到的不满足条件的节点,就是 bigger,最后一次不满足条件的节点,就是 smaller
找到 bigger 和 smaller 之后,我们做一次简单的交换,就可以恢复整棵树了。
痕迹
没有过去,就没法认定现在的自己