1. 程式人生 > 其它 >【LeetCode】C++ :中等題 - 樹 173. 二叉搜尋樹迭代器

【LeetCode】C++ :中等題 - 樹 173. 二叉搜尋樹迭代器

技術標籤:LeetCode# 樹leetcode演算法二叉樹

173. 二叉搜尋樹迭代器

難度中等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;
    }