[LeetCode] C ++:中間問題-ツリー173。二分探索木イテレータ

173.二分探索木イテレータ

中難易度322

二分探索木イテレータを実装します。二分探索木のルートノードでイテレータを初期化します。

呼び出し next() は、バイナリ検索ツリーで次に小さい番号を返します。

 

例:

BSTIterator iterator = new BSTIterator(root); 
iterator.next(); // 3を返す
iterator.next(); // 7を返す
iterator.hasNext(); // trueを返す
iterator.next(); // 9の
イテレータを返す.hasNext(); // trueを返す
iterator.next(); // 15を返す
iterator.hasNext(); // trueを返す
iterator.next(); // 20を返す
iterator.hasNext(); // falseを返す

 

促す:

  • next() 合計 hasNext() 演算の時間計算量はO(1)であり、O(h)メモリを使用します。ここで はツリーの高さです。
  • next() 呼び出しは常に有効であると想定でき ます。つまり、呼び出し next() が行われると、BSTに少なくとも1つの次に小さい番号があります。

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.スタック+反復+中次走査

この質問では、反復法を使用して通常よりも多くの反復を考えます。次の関数では、中次走査を中次走査にすることはできないようです。そのため、次の値は、中次走査の後に小さいノード値を取得します。 、 そう

/**
 * 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;
    }

 

おすすめ

転載: blog.csdn.net/weixin_44566432/article/details/113726485