530 二叉搜索树最小差
var min int
var prev *TreeNode
func getMinimumDifference(root *TreeNode) int {
// 二叉搜索树,中序遍历比较相邻两个元素差,并返回最小绝对差
min = math.MaxInt
prev = nil
inOrder(root)
return min
}
func inOrder(root *TreeNode) {
if root== nil{
return
}
inOrder(root.Left)
if prev != nil {
v := root.Val - prev.Val
if v < min {
min = v
}
}
prev = root
inOrder(root.Right)
return
}
501 二叉搜索树众数
var maxCountVal map[int]int
func findMode(root *TreeNode) []int {
// 出现二叉搜索树,优先考虑特性,即中序遍历单调递增
// 出现众数,中序遍历相邻节点出现次数
// 重新初始化全局变量
maxCountVal = make(map[int]int)
traversal(root, 1)
var max int
for _, v := range maxCountVal{
if v > max {
max = v
}
}
var res []int
for k, v := range maxCountVal{
if v == max {
res = append(res, k)
}
}
return res
}
func traversal(root *TreeNode, count int) {
// 什么时候需要返回值,如果不需要遍历整棵树,或者需要判断树有某种条件(一条路径)或者某个节点值,这时需要遍历中有返回值
// 本题条件需要遍历整颗树,并且已经设置了全局变量作为接收,所以无需返回值
if root == nil {
return
}
traversal(root.Left, count)
maxCountVal[root.Val]++
traversal(root.Right, count)
return
}
// 本质上遍历,存储成hash表,没有用到二叉搜索树特性
var maxCountVal []int
var maxCount, count int
var prev *TreeNode
func findMode(root *TreeNode) []int {
// 出现二叉搜索树,优先考虑特性,即中序遍历单调递增
// 出现众数,中序遍历相邻节点出现次数
// 重新初始化全局变量
maxCountVal = []int{}
maxCount = 0
count = 1
prev = nil
traversal(root)
return maxCountVal
}
func traversal(root *TreeNode) {
// 什么时候需要返回值,如果不需要遍历整棵树,或者需要判断树有某种条件(一条路径)或者某个节点值,这时需要遍历中有返回值
// 本题条件需要遍历整颗树,并且已经设置了全局变量作为接收,所以无需返回值
if root == nil {
return
}
traversal(root.Left)
// 难点在于如何保存众数数组,
// 解决办法就是,如果判断当前count等于最大count,那么就加入结果集,如果大于,清空结果集,加入此元素
if prev != nil {
// fmt.Println(root.Val, prev.Val, count)
if root.Val == prev.Val {
count++
}else {
count = 1
}
}
// fmt.Println("=====",count, maxCount)
if count == maxCount {
maxCountVal = append(maxCountVal, root.Val)
}else if count > maxCount {
maxCountVal = append([]int{}, root.Val)
maxCount = count
}
prev = root
traversal(root.Right)
return
}
236 二叉树最近公共祖先
func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode {
// 回溯,将子节点是否包含p,q的情况一一向上级返回,使用后序遍历
if root == nil {
return nil
}
// 遇到目标节点直接向上级返回
if root == p || root == q {
return root
}
// 后序
left := lowestCommonAncestor(root.Left, p, q)
right := lowestCommonAncestor(root.Right, p, q)
// 根节点即递归单层逻辑
if left != nil && right != nil { // p, q 两个目标节点分布在此节点的左右子树中,那么由于是底层向上返回,所以此时root就是最近公共祖先
return root
}
if left != nil && right == nil { // 如果左子树出现目标节点,将目标节点向上返回,告诉更上级,左子树出现了目标,
// 此时可能两种情况,1,直到最上级仍然右子树没出现目标节点,这时说明p-q是上下级,此时自己就是最近公共祖先
// 2,返回到上级某一级,右子树出现了另一个目标节点,此时就会进入上一个if判断,直接返回上级是公共祖先
return left
}
if left == nil && right != nil {
return right
}
if left == nil && right == nil {
return nil
}
return nil
}