LintCode-86: Binary Search Tree Iterator

86 · Binary Search Tree Iterator
Algorithms
Hard

Description
Design an iterator over a binary search tree with the following rules:
Next() returns the next smallest element in the BST.

Elements are visited in ascending order (i.e. an in-order traversal)
next() and hasNext() queries run in O(1)O(1) time in average.

Example
Example 1:

Input:

tree = {10,1,11,#,6,#,12}
Output:

[1,6,10,11,12]
Explanation:

The BST is look like this:
10
/
1 11
\
6 12
You can return the inorder traversal of a BST [1, 6, 10, 11, 12]

Example 2:

Input:

tree = {2,1,3}
Output:

[1,2,3]
Explanation:

The BST is look like this:
2
/
1 3
You can return the inorder traversal of a BST [1,2,3]

Challenge
Extra memory usage O(h), h is the height of the tree.

Super Star: Extra memory usage O(1)

Tags
Related Problems

448
Inorder Successor in BST
Medium

540
Zigzag Iterator
Medium

541
Zigzag Iterator II
Medium

915
Inorder Predecessor in BST
Medium

解法1:
利用In-Order Traversal的思路。
引用自九章
https://www.jiuzhang.com/solution/binary-search-tree-iterator/#tag-highlight-lang-java

这是一个非常通用的利用 stack 进行 Binary Tree Iterator 的写法。

stack 中保存一路走到当前节点的所有节点,stack.peek() 一直指向 iterator 指向的当前节点。
因此判断有没有下一个,只需要判断 stack 是否为空
获得下一个值,只需要返回 stack.peek() 的值,并将 stack 进行相应的变化,挪到下一个点。

挪到下一个点的算法如下:

如果当前点存在右子树,那么就是右子树中“一路向西”最左边的那个点
如果当前点不存在右子树,则是走到当前点的路径中,第一个左拐的点

注意:

  1. 该方法的next()的平均时间复杂度是O(1)。因为不管什么样的二叉树,每个节点都只进/出栈一次。平均起来,时间复杂度就是O(1)。
    最坏时间复杂度应该是O(n)???
/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 * Example of iterate a tree:
 * BSTIterator iterator = BSTIterator(root);
 * while (iterator.hasNext()) {
 *    TreeNode * node = iterator.next();
 *    do something for node
 */


class BSTIterator {
public:
    /*
    * @param root: The root of binary tree.
    */
    BSTIterator(TreeNode * root) {
        while(root) {
            s.push(root);
            root=root->left;
        }
    }

    /*
     * @return: True if there has next node, or false
     */
    bool hasNext() {
        return !s.empty();
    }

    /*
     * @return: return next node
     */
    TreeNode * next() {
        TreeNode* node = s.top();
        TreeNode* retNode = node;
        
        if (node->right) {
            node = node->right;
            while (node) {
                s.push(node);
                node = node->left;
            }
        } else {
            node = s.top();
            s.pop();
            while(!s.empty() && s.top()->right == node) {
                node = s.top();
                s.pop();
            }
        }
        
        return retNode;
    }
    
private:
    stack<TreeNode*> s;
};

二刷:

/**
 * Definition of TreeNode:
 * class TreeNode {
 * public:
 *     int val;
 *     TreeNode *left, *right;
 *     TreeNode(int val) {
 *         this->val = val;
 *         this->left = this->right = NULL;
 *     }
 * }
 * Example of iterate a tree:
 * BSTIterator iterator = BSTIterator(root);
 * while (iterator.hasNext()) {
 *    TreeNode * node = iterator.next();
 *    do something for node
 */
class BSTIterator {
public:
    /*
    * @param root: The root of binary tree.
    */
    BSTIterator(TreeNode * root) {
        cur = root;
    }

    /*
     * @return: True if there has next node, or false
     */
    bool hasNext() {
        return cur || !stk.empty();
    }

    /*
     * @return: return next node
     */
    TreeNode * next() {
        while (cur) {
            stk.push(cur);
            cur = cur->left;
        }
        cur = stk.top();
        stk.pop();
        TreeNode *res = cur;
        cur = cur->right;
        return res;
    }
private:
    TreeNode *cur;
    stack<TreeNode *> stk;
};

注意:上面的next()就是in-order traversal里面的两个while()循环去掉第一个while()循环。

vector<int> inorderTraversal(TreeNode *root) {
        stack<TreeNode *> stk;
        vector<int> res;
        while (root || !stk.empty()) {
            while (root) {
               stk.push(root);
               root = root->left;
            }
            root = stk.top();
            stk.pop();
            res.push_back(root->val);
            root = root->right;
        }
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值