Leetcode算法学习日志-173 Binary Search Tree Iterator

来源:互联网 发布:保险资产管理公司 知乎 编辑:程序博客网 时间:2024/05/29 17:54

Leetcode 173 Binary Search Tree Iterator

题目原文

Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.

Calling next() will return the next smallest number in the BST.

Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, whereh is the height of the tree.

提议分析

设计一个迭代器类,其中成员函数next()能够得到一个二叉搜索树的下一个最小元素,hasNext()能够判断是否还有下一个最小元素。两个函数的时间复杂度在平均情况下都是O(1),空间复杂度在平均情况下是O(h),h为树高。

解法分析

二叉搜索树通常用链表结构实现,可以实现基本的字典操作,常用来作为一个字典或是优先队列。二叉搜索树的特点是每一个节点的左子树节点关键字都不大于它,右节点关键字都不小于它,采用中序遍历二叉树,可以在O(n)时间下得到所有元素的升序排列,其他字典操作时间复杂度为O(h)。值得注意的是,同一组数可以由不同的二叉搜索树表示,但搜索效率不同,平均情况下,随机构造的二叉搜索树平均高度为O(lgn)。本题利用了二叉搜索树的中序遍历过程,标准中序遍历递归过程如下:

inorder(x)   if(x!=NULL)        inorder(x->left);        cout<<x->value;        inorder(x->right);
上述递归穿参过程隐含了一个栈操作。

本题我的最初解法如下:

class BSTIterator {private: deque<int> myQue;public:    void makeQue(TreeNode *r){        if(r!=NULL){             makeQue((*r).left);             myQue.push_back((*r).val);             makeQue((*r).right);           }           }    BSTIterator(TreeNode *root) {        makeQue(root);     }    /** @return whether we have a next smallest number */    bool hasNext() {        return !myQue.empty();      }    /** @return the next smallest number */    int next() {        return myQue[0];        myQue.pop_front();      }};
将中序遍历存储的结果存到一个队列中,再在next里按序pop,这样虽然结果正确,但是空间消耗为O(n),而非O(h)。因此要模拟inorder的栈操作,使得栈高最多为h。C++代码如下:

/** * Definition for binary tree * struct TreeNode { *     int val; *     TreeNode *left; *     TreeNode *right; *     TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */class BSTIterator {private:    stack<TreeNode*> myStack;public:    void pushLeft(TreeNode *r){        while(r!=NULL){//it can be in recursion form            myStack.push(r);            r=(*r).left;        }            }    BSTIterator(TreeNode *root) {        pushLeft(root);            }    /** @return whether we have a next smallest number */    bool hasNext() {        return !myStack.empty();            }    /** @return the next smallest number */    int next() {        TreeNode *temp=myStack.top();        myStack.pop();        pushLeft((*temp).right);//simulate the stack of calling recursion functions        return ((*temp).val);        }};/** * Your BSTIterator will be called like this: * BSTIterator i = BSTIterator(root); * while (i.hasNext()) cout << i.next(); */
利用pushLeft函数将某节点以及其左子树的所有左节点入栈,模拟左-根-右的左,在构造函数中让栈达到左子树最深处的一个左儿子,然后在next中pop它并输出,此时进入该节点的右子树调用pushLeft,模拟inorder中的第三句。

本题用到的C++知识如下:

  • queue和stack均是用deque构造的两个容器,拥有一些新的用法,如q.front(),q.back(),s.top(),注意他们的pop()均只是pop掉,而不返回。


原创粉丝点击