【LeetCode】C++ :中等題 - 樹 173. 二叉搜尋樹迭代器
阿新 • • 發佈:2021-02-07
技術標籤:LeetCode# 樹leetcode演算法二叉樹
難度中等322
實現一個二叉搜尋樹迭代器。你將使用二叉搜尋樹的根節點初始化迭代器。
呼叫
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 中至少存在一個下一個最小的數。
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 { private: vector<int> vec; int index = 0; public: BSTIterator(TreeNode* root) { midTraverse(root, vec); } int next() { return vec[index++]; } // hasNext() 函式的作用是:返回一個布林值,表示二叉搜尋樹中是否還有元素 bool hasNext() { return index != vec.size(); } void midTraverse(TreeNode* root, vector<int>& res){ if(root == nullptr){ return ; } midTraverse(root->left, res); res.push_back(root->val); midTraverse(root->right, res); } }; /** * Your BSTIterator object will be instantiated and called as such: * BSTIterator* obj = new BSTIterator(root); * int param_1 = obj->next(); * bool param_2 = obj->hasNext(); */
2、棧 + 迭代 + 中序遍歷
這題用迭代方式比通常的迭代要多一些思考,在next函式裡面,看似中序遍歷卻不能是中序遍歷,因此next值獲取的是中序遍歷後的較小節點值,因此
/** * 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) { p = root; } int next() { hasNext(); int res; while(p != nullptr || !stk.empty()){ if(p != nullptr){ stk.push(p); p = p->left; }else{ p = stk.top(); stk.pop(); res = p->val; p = p->right; break; } } return res; } bool hasNext() { return p || !stk.empty(); } private: TreeNode* p; stack<TreeNode*> stk; }; /** * Your BSTIterator object will be instantiated and called as such: * BSTIterator* obj = new BSTIterator(root); * int param_1 = obj->next(); * bool param_2 = obj->hasNext(); */
下面這樣的獲取next() 記一下吧,每次執行next獲取的都是中序遍歷後的序列值
int next() {
hasNext();
int res;
while(p != nullptr || !stk.empty()){
while(p != nullptr){
stk.push(p);
p = p->left;
}
if(p == nullptr){
p = stk.top();
stk.pop();
res = p->val;
p = p->right;
break;
}
}
return res;
}