leetcode
二叉搜索树(BST)的一个重要性质是,对其进行中序遍历可以得到一个按节点值升序排列的序列。在一个升序序列里,最小的差值必然出现在相邻的两个元素之间。因此,我们可以对给定的二叉搜索树进行中序遍历,在遍历过程中记录相邻节点值的差值,进而找出其中的最小值。
- 定义节点结构:定义二叉树节点的结构体,包含节点值以及左右子节点指针。
- 中序遍历函数:编写一个中序遍历函数,在遍历过程中记录前一个节点的值和当前的最小差值。
- 递归遍历左子树。
- 计算当前节点值与前一个节点值的差值,并更新最小差值。
- 更新前一个节点的值为当前节点的值。
- 递归遍历右子树。
- 初始化变量:初始化前一个节点的值为一个特殊值(这里用 -1 表示还未遇到节点),最小差值初始化为最大整数。
- 调用中序遍历函数:从根节点开始进行中序遍历。
- 返回结果:返回计算得到的最小差值。
package main
import (
"fmt"
"math"
)
// TreeNode 定义二叉树节点结构
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
// getMinimumDifference 计算二叉搜索树中任意两不同节点值之间的最小差值
func getMinimumDifference(root *TreeNode) int {
// 初始化前一个节点的值为 -1,表示还未遇到节点
prev := -1
// 初始化最小差值为最大整数
minDiff := math.MaxInt32
// 定义中序遍历函数
var inorder func(node *TreeNode)
inorder = func(node *TreeNode) {
if node == nil {
return
}
// 递归遍历左子树
inorder(node.Left)
// 如果 prev 不为 -1,说明已经遇到过节点,计算当前节点值与前一个节点值的差值
if prev != -1 {
diff := node.Val - prev
if diff < minDiff {
minDiff = diff
}
}
// 更新 prev 为当前节点的值
prev = node.Val
// 递归遍历右子树
inorder(node.Right)
}
// 开始中序遍历
inorder(root)
return minDiff
}
- 时间复杂度:O(n),其中 n 是二叉搜索树中的节点数量。因为需要对二叉搜索树进行一次完整的中序遍历,每个节点恰好被访问一次。
- 空间复杂度:O(h),其中 h 是二叉搜索树的高度。主要的空间开销是递归调用栈的深度,最坏情况下(二叉搜索树退化为链表),空间复杂度为 O(n);平均情况下,空间复杂度为 O(logn)。
对于输入 root = [4,2,6,1,3],对应的二叉搜索树结构如下:
- 中序遍历的顺序为:1→2→3→4→6。
- 计算相邻节点值的差值:
- ∣2−1∣=1
- ∣3−2∣=1
- ∣4−3∣=1
- ∣6−4∣=2
- 最小差值为 1,所以最终结果返回 1。
func main() {
// 构建示例二叉搜索树 [4,2,6,1,3]
root := &TreeNode{Val: 4}
root.Left = &TreeNode{Val: 2}
root.Right = &TreeNode{Val: 6}
root.Left.Left = &TreeNode{Val: 1}
root.Left.Right = &TreeNode{Val: 3}
// 调用函数计算最小差值
result := getMinimumDifference(root)
fmt.Println(result) // 输出: 1
}