Description
給定一棵 BST 的根節點和整數 k,回傳 BST 中第 k 小的元素(1-indexed)。
Example:
Input: root = [3,1,4,null,2], k = 1 Output: 1
Intuition#
BST 中序遍歷是有序的,第 k 個被訪問的節點就是答案。
- 中序遍歷 BST 得到遞增序列,遍歷到第 k 個就可以提前停止
- 不需要真的收集所有元素,用計數器即可
Approaches#
1: 中序遍歷收集全部元素#
- 概念: 完整中序遍歷收集所有值到列表,回傳第 k-1 個元素
- 時間複雜度:
O(n) - 空間複雜度:
O(n)
class Solution {
fun kthSmallest(root: TreeNode?, k: Int): Int {
val list = mutableListOf<Int>()
inorder(root, list)
return list[k - 1]
}
private fun inorder(node: TreeNode?, list: MutableList<Int>) {
if (node == null) return
inorder(node.left, list)
list.add(node.`val`)
inorder(node.right, list)
}
}⭐ 2: 中序遍歷 + 提前停止(Iterative)#
- 概念: 迭代式中序遍歷,計數到 k 就立即回傳
- 時間複雜度:
O(h + k),h 為樹高 - 空間複雜度:
O(h)
class Solution {
fun kthSmallest(root: TreeNode?, k: Int): Int {
val stack = ArrayDeque<TreeNode>()
var current = root
var count = 0
while (current != null || stack.isNotEmpty()) {
while (current != null) {
stack.addLast(current)
current = current.left
}
current = stack.removeLast()
count++
if (count == k) return current.`val`
current = current.right
}
return -1 // 不會到達
}
}迭代式中序遍歷模板
迭代式中序遍歷的核心模式:
- 先一路往左走到底,把沿途節點推入堆疊
- 彈出堆疊頂端(當前最小未處理節點)
- 處理該節點
- 轉向右子樹,重複步驟 1
這個模板可以用在很多 BST 問題上。
🔑 Takeaways#
- Pattern: BST + 中序遍歷 = 有序序列,第 k 小/大問題直接解決
- 關鍵技巧: 迭代式中序遍歷可以在找到答案後提前停止,比遞迴更容易控制提前終止