Description
給定一棵 BST 的根節點,回傳任意兩個不同節點之間的最小差值。此最小差值一定出現在中序遍歷的相鄰節點之間。
Example:
Input: root = [4,2,6,1,3] Output: 1 (相鄰節點 2 和 3 的差值)
Intuition#
BST 的中序遍歷產生有序序列,最小差值一定出現在相鄰元素之間。
- BST 中序遍歷是嚴格遞增的
- 最小差值只可能出現在排序後的相鄰元素之間,因此只需要在中序遍歷時比較當前節點與前一個節點的差值
Approaches#
⭐ 1: 中序遍歷 (Recursive)#
- 概念: 中序遍歷 BST,持續追蹤前一個節點值,比較相鄰差值取最小
- 時間複雜度:
O(n),遍歷所有節點 - 空間複雜度:
O(h),遞迴堆疊深度
class Solution {
private var prev: Int? = null
private var minDiff = Int.MAX_VALUE
fun minDiffInBST(root: TreeNode?): Int {
prev = null
minDiff = Int.MAX_VALUE
inorder(root)
return minDiff
}
private fun inorder(node: TreeNode?) {
if (node == null) return
inorder(node.left)
prev?.let { minDiff = minOf(minDiff, node.`val` - it) }
prev = node.`val`
inorder(node.right)
}
}2: 中序遍歷 (Iterative)#
- 概念: 用 Stack 迭代中序遍歷,同樣追蹤前一個值比較差值
- 時間複雜度:
O(n) - 空間複雜度:
O(h)
class Solution {
fun minDiffInBST(root: TreeNode?): Int {
var minDiff = Int.MAX_VALUE
var prev: Int? = null
val stack = ArrayDeque<TreeNode>()
var curr = root
while (curr != null || stack.isNotEmpty()) {
while (curr != null) {
stack.addLast(curr)
curr = curr.left
}
curr = stack.removeLast()
prev?.let { minDiff = minOf(minDiff, curr!!.`val` - it) }
prev = curr!!.`val`
curr = curr.right
}
return minDiff
}
}🔑 Takeaways#
- Pattern: BST + 中序遍歷 — 利用 BST 的有序性質將問題轉化為有序序列問題
- 關鍵技巧: BST 中任意兩節點的最小差值一定在中序遍歷的相鄰節點間,不需要兩兩比較