1. 程式人生 > 遊戲 >『泡沫冬景』全新篇章「和平默示錄」體驗版“序曲”現已開放!

『泡沫冬景』全新篇章「和平默示錄」體驗版“序曲”現已開放!

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()

操作時,將棧頂節點右兒子的左節點全部入棧,這樣最壞情況為 O ( n ) O(n) O(n),均攤情況下為 O ( 1 ) O(1) O(1)

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%
*/