『泡沫冬景』全新篇章「和平默示錄」體驗版“序曲”現已開放!
阿新 • • 發佈:2021-03-03
173. 二叉搜尋樹迭代器
題目描述
實現一個二叉搜尋樹迭代器。你將使用二叉搜尋樹的根節點初始化迭代器。
呼叫 next()
將返回二叉搜尋樹中的下一個最小的數。
示例:
BSTIterator iterator = new BSTIterator(root); iterator.next(); // 返回 3 iterator.next(); // 返回 7 iterator.hasNext(); // 返回 true iterator.next(); // 返回 9 iterator.hasNext(); // 返回 true iterator.next(); // 返回 15 iterator.hasNext(); // 返回 true iterator.next(); // 返回 20 iterator.hasNext(); // 返回 false
提示:
-
next()
和hasNext()
操作的時間複雜度是 O(1),並使用 O(h) 記憶體,其中 h 是樹的高度。 -
你可以假設
next()
呼叫總是有效的,也就是說,當呼叫next()
時,BST 中至少存在一個下一個最小的數。
題解:
觀察 next()
是返回二叉搜尋樹中下一個最小值,而二叉搜尋樹有一個重要的特徵:中序遍歷是遞增序列 ,那麼就可以考慮用 中序遍歷 來搞事情。
直觀想法是:中序遍歷將值儲存起來,然後 next()
時依次取出來即可,但是這種情況下,空間複雜度為
O
(
n
)
O(n)
O(n) ,與
O
(
h
)
O(h)
O(h) 不符。
可以考慮將非遞迴中序遍歷,每次 next()
hasNext()
操作可直接判斷棧是否為空。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class BSTIterator {
public:
BSTIterator(TreeNode* root) {
moveLeft( root );
}
void moveLeft(TreeNode* root) {
while ( root ) {
stk.push(root);
root = root->left;
}
}
int next() {
auto now = stk.top();
stk.pop();
int val = now->val;
now = now->right;
moveLeft( now );
return val;
}
bool hasNext() {
return !stk.empty();
}
private:
stack<TreeNode*> stk;
};
/*
時間:24ms,擊敗:97.68%
記憶體:23.4MB,擊敗:93.26%
*/
還可以考慮將 二叉搜尋樹 轉換成 單鏈表,利用節點空閒的右指標,Morris遍歷 將其改造成一個單鏈表。
時間複雜度: O ( n ) O(n) O(n)
額外空間複雜度: O ( 1 ) O(1) O(1)
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class BSTIterator {
public:
BSTIterator(TreeNode* root) {
now = root;
}
int next() {
while( now ) {
auto mostright = now->left;
if( mostright ) {
while ( mostright->right && mostright->right != now )
mostright = mostright->right;
if ( !mostright->right ) {
mostright->right = now;
now = now->left;
continue;
}
}
break;
}
int val = now->val;
now = now->right;
return val;
}
bool hasNext() {
return now != nullptr;
}
private:
TreeNode *now;
};
/*
時間:32ms,擊敗:86.96%
記憶體:23.4MB,擊敗:93.62%
*/