代码随想录day18 || 530 二叉搜索树最小差,501 二叉搜索树众数,236 二叉搜索树最近公共祖先

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
}
posted @ 2024-08-03 11:57  周公瑾55  阅读(14)  评论(0)    收藏  举报