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

包含min函数的栈

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

题目主要信息:
  • 实现栈的push、pop、top、min函数
  • 访问每个函数的时间复杂度为O(1)O(1)
举一反三:

学习完本题的思路你可以解决如下题目:

BM42.用两个栈实现队列

方法:双栈法(推荐使用)

知识点:栈

栈是一种仅支持在表尾进行插入和删除操作的线性表,这一端被称为栈顶,另一端被称为栈底。元素入栈指的是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;元素出栈指的是从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

思路:

我们都知道栈结构的push、pop、top操作都是O(1)O(1),但是min函数做不到,于是想到在push的时候就将最小值记录下来,由于栈先进后出的特殊性,我们可以构造一个单调栈,保证栈内元素都是递增的,栈顶元素就是当前最小的元素。

具体做法:

  • step 1:使用一个栈记录进入栈的元素,正常进行push、pop、top操作。
  • step 2:使用另一个栈记录每次push进入的最小值。
  • step 3:每次push元素的时候与第二个栈的栈顶元素比较,若是较小,则进入第二个栈,若是较大,则第二个栈的栈顶元素再次入栈,因为即便加了一个元素,它依然是最小值。于是,每次访问最小值即访问第二个栈的栈顶。
//空或者新元素较小,则入栈
if(s2.isEmpty() || s2.peek() > node)  
    s2.push(node);
else
    //重复加入栈顶
    s2.push(s2.peek());

图示:

图片说明

Java实现代码:

import java.util.Stack;

public class Solution {
    //用于栈的push 与 pop
    Stack<Integer> s1 = new Stack<Integer>(); 
    //用于存储最小min
    Stack<Integer> s2 = new Stack<Integer>(); 
    public void push(int node) {
        s1.push(node);  
        //空或者新元素较小,则入栈
        if(s2.isEmpty() || s2.peek() > node)  
            s2.push(node);
        else
            //重复加入栈顶
            s2.push(s2.peek());  
    }
    
    public void pop() {
        s1.pop();
        s2.pop();
    }
    
    public int top() {
        return s1.peek();
    }
    
    public int min() {
        return s2.peek();
    }
}

C++实现代码:

class Solution {
public:
    //用于栈的push 与 pop
    stack<int> s1;  
    //用于存储最小min
    stack<int> s2;  
    void push(int value) {
        s1.push(value);  
        //空或者新元素较小,则入栈
        if(s2.empty() || s2.top() > value)  
            s2.push(value);
        else
            //重复加入栈顶
            s2.push(s2.top());  
    }
    void pop() {
        s1.pop();
        s2.pop();
    }
    int top() {
        return s1.top();
    }
    int min() {
        return s2.top();
    }
};

Python代码实现:

class Solution:
    def __init__(self):
        self.s1 = []
        self.s2 = []
    def push(self, node):
        self.s1.append(node)  
        #空或者新元素较小,则入栈
        if len(self.s2) == 0 or self.s2[-1] > node:  
            self.s2.append(node)
        else:
            #重复加入栈顶
            self.s2.append(self.s2[-1])  
    def pop(self):
        self.s1.pop()
        self.s2.pop()
    def top(self):
        return self.s1[-1]
    def min(self):
        return self.s2[-1]

复杂度分析:

  • 时间复杂度:O(1)O(1),每个函数访问都是直接访问,无循环
  • 空间复杂度:O(n)O(n),s1为必要空间,s2为辅助空间
全部评论
双栈实现MIN功能确实不错,但是其他的部分,我用一个栈容器实现题目要求的栈数据结构的功能,是不是有点奇怪
1 回复 分享
发布于 2023-02-19 16:04 广东
大赞,刚开始有一点疑惑的是如果栈1pop了栈2的top作为最小值是否还有效, 直到看到了s2.push(s2.top());这个栈2重复加入栈顶的操作, 可以说只要在栈1中这个值还存在,栈2的top就一定是这个值,有种生命周期的感觉了,哈哈
1 回复 分享
发布于 2022-11-14 18:12 陕西
写的很好,就是演示动画好快,看了好几遍
1 回复 分享
发布于 2022-11-09 00:00 新疆
重复压入这个真的是巧妙,不知道是如何想出来的
点赞 回复 分享
发布于 2024-10-30 09:59 广东
官方题解这么冷清。。。。
点赞 回复 分享
发布于 2022-05-01 18:32

相关推荐

来个大佬救一下,为上投了都是石沉大海了,没实习经历的话怕秋招直接进不了面。什么实习这么难找,基本
心态爆炸了:现在正式的岗位都少,实习基本不咋招的,除了大厂,中小企业其实没那么多岗位需求,就算是有,大多都是招一两个廉价劳动力,同时,他们也会希望你一来就能干活的,没时间培训你,就让你了解公司的项目,你了解完就可以开始干活。再者是,很多低质量的实习其实用处没有那么大的。我去年也是找实习找到破防,最后去了一家深圳的小公司实习,工作对我来说很简单,甚至不如我在学校做的项目,秋招的时候,这段实习经历也并没有帮上什么忙,投递简历,依旧非常低的回复率。低回复率是常态,尤其是找实习,找不到,那就把重心放在优化自己的简历和项目,多看八股文,锻炼自己的面试能力,多看别人的面经,自己模拟面试,等秋招的时候,只要有那么寥寥几次,好好抓住那几次机会。
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-08 11:16
点赞 评论 收藏
分享
06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
05-26 22:25
门头沟学院 Java
Java小肖:不会是想叫你过去把你打一顿吧,哈哈哈
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-07 12:04
毕业生招你惹你了,问一个发薪日来一句别看网上乱七八糟的你看哪个工作没有固定发薪日扭头就取消了面试就问了一句公司都是这个态度吗还搞上人身攻击了...
程序员小白条:呃呃呃,都还没面试,我都不会问这么细,何况通不通过,去不去都另说,你没实力和学历的话,在外面就这样,说实话没直接已读不回就不错了,浪费时间基本上
点赞 评论 收藏
分享
评论
35
4
分享

创作者周榜

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