LeetCode「二叉搜索樹迭代器」要求實現 next() 和 hasNext(),平均 O(1) 時間、O(h) 空間(h 為樹高)。本文解析基於顯式棧模擬中序遍歷的標準解法,並說明為什麼這是面試高頻考點。
next() 返回下一個最小值 → 即中序遍歷的下一個節點。next() 時展開必要的節點。從根節點出發,沿左子節點不斷入棧,直到最左葉節點。棧頂即為最小值節點。
BSTIterator(TreeNode* root) {
while (root) {
st.push(root);
root = root->left;
}
}
bool hasNext() {
return !st.empty();
}
cur,其值即為返回值。cur->right 存在,將其作為新根,重複「壓入左鏈」過程:沿右子節點的左鏈入棧。cur->val。int next() {
TreeNode* cur = st.top(); st.pop();
if (cur->right) {
TreeNode* p = cur->right;
while (p) {
st.push(p);
p = p->left;
}
}
return cur->val;
}
class BSTIterator {
stack<TreeNode*> st;
public:
BSTIterator(TreeNode* root) {
while (root) {
st.push(root);
root = root->left;
}
}
bool hasNext() { return !st.empty(); }
int next() {
TreeNode* cur = st.top(); st.pop();
if (cur->right) {
TreeNode* p = cur->right;
while (p) {
st.push(p);
p = p->left;
}
}
return cur->val;
}
};
next() 總操作數 2n → 攤還 O(1)。class BSTIterator {
Deque<TreeNode> stack = new ArrayDeque<>();
public BSTIterator(TreeNode root) { pushLeft(root); }
private void pushLeft(TreeNode node) {
while (node != null) { stack.push(node); node = node.left; }
}
public boolean hasNext() { return !stack.isEmpty(); }
public int next() {
TreeNode cur = stack.pop();
if (cur.right != null) pushLeft(cur.right);
return cur.val;
}
}
BST 迭代器是「棧模擬遞歸」的教科書級應用。關鍵洞察:中序遍歷的下一個節點 = 當前節點右子樹的最左節點(若存在),否則是祖先鏈中第一個當前節點在其左子樹中的祖先。棧自然維護了這條祖先鏈。掌握此模板,可舉一反三解決所有樹的非遞歸遍歷問題。