题解 | #包含min函数的栈#

包含min函数的栈

http://www.nowcoder.com/practice/4c776177d2c04c2494f2555c9fcc1e49

C++:利用map实现整体时间复杂度O(1)

vector实际上就是一个stack的封装类。所以直接用vector的成员函数就可以很容易的实现栈的基础操作。

public:
    vector<int> pool;

    void push(int value) {
        //不能这么写:pool[head] = value; 在最开始,vector没有申请到任何空间,因此pool[head]这个访问操作
        //是非法的。访问操作不会申请额外空间。
        pool.push_back(value);
    }

    void pop() {
        pool.pop_back();
    }

    int top() {
        return pool.back();
    }

重点在这:

请在该类型中实现一个能够得到栈中所含最小元素的min函数(时间复杂度应为O(1))。

最容易想到的方法当然是从头到尾查询整个栈中最小值,但这个方法是O(N)的,显然不可行。
当然你也可以把这个时间成本转移到其他函数:
维护一个int类的mini变量,在每一次对栈有修改,即入栈push或出栈pop操作完成后,从头到尾查询栈中的最小值,用该值更新mini。调用min()函数时直接返回mini的值即可。
题目是过了,但其实也只是在骗自己XD,面试官当然不会对这个答案感到满意。

我给出的解决方案是:使用键值对数组map以空间换时间
维护一个键和值都为int类型的map容器times,在每次对栈进行修改时,我们在times中进行相应的“记录”。

public:
    vector<int> pool;
    map<int,int> times;//<栈中元素的值,出现次数>

    void push(int value) {
        pool.push_back(value);
        times[value]++;//使times中键为value的值++
    }

    void pop() {
        //将即将出栈的元素作为键,使其对应的值--,并检查该值是否还在栈中存在(出现次数是否为0)
        if(--times[pool.back()] == 0)
        {
            times.erase(pool.back());//已不在栈中存在的值,我们将其对应的键值对从times中移除掉
        }
        pool.pop_back();
    }
    int top() {
        return pool.back();
    }

对于键值对map容器来说,通过下标访问/修改一个键的值,就像我们所熟知的int类数组通过下标访问一个元素一样,时间复杂度是都是O(1),所以更新栈操作push、pop的时间复杂度也为O(1)。
注意当一个数不再存在在栈中时,我们要将其从times中移除掉,而不是只将他的值改为0。否则最后这招就不好使了:

int min() {
        return times.begin()->first;
    }

map容器中的各个元素是按 键key 进行排序的。对于int类型的键自然是按大小排序了,所以times中的第一个元素times.begin()的键就是我们要找的最小值。用->first访问一个键值对的键,用->second来得到它的值。

这样,整个类中的各个函数我们都实现了时间复杂度为O(1)。

全部评论

相关推荐

首先讲三个故事,关于牛客的事件一:2024年,牛客上有一对高学历情侣,求职方向与我当时一致,都是嵌入式方向。他们恰好是我的朋友,专业能力和学历背景都很扎实,也因此拿到了不少优质offer。和很多求职者一样,他们把offer情况整理后发在平台上,本意是记录与交流,但很快引发了争议。有声音指责他们“集邮”“不释放名额”,认为这种展示本身就是一种炫耀。最终讨论失控,当事人删除内容,事件也很快被遗忘。事件二:小红书评论区,一条评价获得了不少共鸣:“感觉牛客就是当年那群做题区毕业了开始找工作还收不住那股味,颇有一种从年级第一掉到年纪第二后抱怨考不上大学的味道”,这条评论被水印里这个同学转发到牛客后,评论...
小型域名服务器:当看到别人比自己强的时候,即便这是对方应得的,很多人会也下意识的歪曲解构对方的意图,来消解自己在这本就不存在的比较中输掉的自信,从而平白制造出很多无谓的争论。比如你会在空余时间来写优质好文,而我回家只会暗区突围,那么我就可以作为键盘侠在这里评论你是不是XXXXXXXX。即便我自己都知道这是假的,但只要这没那么容易证伪,那么当你开始回应的时候,脏水就已经泼出去了,后面可能会有更多的人带着情绪来给我点赞,而毫不关注你写的文章内容本身是啥了。
SAGIMA牛马咖啡
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务