LintCode 12.带最小值操作的栈(两种方法实现)
题目描述
实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值。
你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成。
样例
如下操作:push(1),pop(),push(2),push(3),min(), push(1),min() 返回 1,2,1
先审题,返回值为1,2,1,分别是 pop(),min(),min() 这三个操作返回的值;在一般栈结构的基础上实现min方法来返回当前栈中的最小值,
我们可以增加一个辅助栈结构,用来记录当前栈的最小值。
手动推导一遍样例(方法1)
|
操作 |
当前栈:datastack |
辅助栈:minstack |
返回值 |
|
push(1) |
1 |
1 |
|
|
pop() |
空 |
空 |
1 |
|
push(2) |
2 |
2 |
|
|
push(3) |
2,3 |
2,2 |
|
|
min() |
2,3 |
2,2 |
2 |
|
push(1) |
2,3,1 |
2,2,1 |
|
|
min() |
2,3,1 |
2,2,1 |
1 |
从上表的推导过程来看,当前栈的 push(),pop()操作与一般栈无区别,新添加的 min() 操作每次返回的是当前栈中的最小值元素,即辅助栈的栈顶元素;
而增加的辅助栈在 push() 操作上做了一点改变,每次压栈时,若当前元素 <= 辅助栈栈顶元素时,则将当前元素压入栈,否则,继续压入辅助栈栈顶元素;
实现代码:
import java.util.Stack;
public class MinStack {
public static void main(String[] args) {
MinStack stack = new MinStack();
stack.push(1);
stack.pop();
stack.push(2);
stack.push(3);
stack.min();
stack.push(1);
stack.min();
}
Stack<Integer> datastack = new Stack<Integer>();
Stack<Integer> minstack = new Stack<Integer>();
/*当前栈压栈,1)最小值栈为空时,将该元素记录为最小值栈栈顶元素;2)最小值栈非空时,将该元素与最小值栈栈顶元素比较,谁小谁入栈;*/
public void push(int num) {
int top;
datastack.push(num);
if(!minstack.empty())
top = minstack.peek();
else
top = num;
if(num > top)
minstack.push(top);
else
minstack.push(num);
//System.out.println("push"+num+"时当前栈的栈顶元素为:"+datastack.peek());
//System.out.println("push"+num+"时最小值栈的栈顶元素为:"+minstack.peek());
}
/*返回当前栈栈顶元素,当前栈与最小值栈同时出栈;*/
public int pop() {
if(!datastack.isEmpty()) {
int data = datastack.peek();
datastack.pop();
minstack.pop();
//return data;
System.out.println("当前栈中的最小值为:"+ data);
}
return 0;
}
/*判断当前栈是否非空,返回当前栈中的最小值,即最小值栈的栈顶元素;*/
public int min() {
if(!datastack.isEmpty()) {
//return minstack.peek();
System.out.println("当前栈中的最小值为:"+minstack.peek());
}
return 0;
}
}
手动推导一遍样例(方法2)
|
操作 |
当前栈:datastack |
辅助栈:minstack |
返回值 |
|
push(1) |
1 |
1 |
|
|
pop() |
空 |
空 |
1 |
|
push(2) |
2 |
2 |
|
|
push(3) |
2,3 |
2 |
|
|
min() |
2,3 |
2 |
2 |
|
push(1) |
2,3,1 |
2,1 |
|
|
min() |
2,3,1 |
2,1 |
1 |
方法2与方法1区别在于,第一点:方法2使用LinkedList数据结构来实现栈,而不是如方法1中直接使用Stack来实现栈;
第二点:方法2的辅助栈的 push() 操作只在栈为空或者当前元素 < 辅助栈栈顶元素时,才压栈;pop() 操作时,只有在栈顶元素与当前栈出栈元素相同时才出栈。
实现代码:
import java.util.LinkedList;
public class MinStack {
public static void main(String[] args) {
MinStack stack = new MinStack();
stack.push(1);
stack.pop();
stack.push(2);
stack.push(3);
stack.min();
stack.push(1);
stack.min();
}
LinkedList datastack = new LinkedList<Integer>();
LinkedList minstack = new LinkedList<Integer>();
/* 当前栈压栈,最小值栈为空时或者该元素比最小值栈栈顶元素小时压栈 */
public void push(int num) {
datastack.addFirst(num);
if(minstack.isEmpty()||num <= (int)minstack.getFirst()) {
minstack.addFirst(num);
}
}
/* 判断当前栈非空,则出栈,若出栈元素与最小值栈栈顶元素相同,则也须出栈 */
public int pop() {
int data;
if(!datastack.isEmpty()) {
data = (int)datastack.removeFirst();
if(data == (int)minstack.getFirst()) {
minstack.removeFirst();
}
//return data;
System.out.println(data);
}
return 0;
}
/* 返回最小值栈的栈定元素即所求的最小元素 */
public int min() {
if(!datastack.isEmpty()) {
return (int)minstack.getFirst();
//System.out.println((int)minstack.getFirst());
}
return 0;
}
}
总结:方法1与方法2在LintCode上均提交成功,运行时间分别为 2042ms 和 2088ms .
直接使用Stack类实现栈,理解简单易上手,重点掌握其 push()、pop()、peek()等方法;而使用LinkedLIst类来实现栈,这里只是为了加强LinkedList的练习,
重点掌握其 addFirst()、getFirst()、removeFirst() 等方法;同时还可以用ArrayList类来实现栈。
LintCode 12.带最小值操作的栈(两种方法实现)的更多相关文章
- lintcode12 带最小值操作的栈
实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值. 你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成. 建一个栈helpStack,用来存放从 ...
- LintCode-12.带最小值操作的栈
带最小值操作的栈 实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值. 你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成. 注意事项 如果堆栈中 ...
- Linux 下操作GPIO(两种方法,驱动和mmap)(转载)
目前我所知道的在Linux下操作GPIO有两种方法: 1.编写驱动,这当然要熟悉Linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据io ...
- Linux 下操作gpio(两种方法,驱动和mmap)
目前我所知道的在linux下操作GPIO有两种方法: 1. 编写驱动,这当然要熟悉linux下驱动的编写方法和技巧,在驱动里可以使用ioremap函数获得GPIO物理基地址指针,然后使用这个指针根据 ...
- 带最小值操作的栈 · Min Stack
[抄题]: 实现一个带有取最小值min方法的栈,min方法将返回当前栈中的最小值. 你实现的栈将支持push,pop 和 min 操作,所有操作要求都在O(1)时间内完成. [思维问题]: [一句话思 ...
- [LintCode] 带最小值操作的栈
class MinStack { public: MinStack() { // do initialization if necessary } void push(int number) { // ...
- Mysql使用binlog恢复数据解决误操作问题的两种方法
为保证没有其他参数配置影响,重新安装配置了一台最小化安装的CentOS7虚拟机 1. 基础知识 安装mysql5.6数据库Mysql binlog初步理解 2. 配置mysql 开启binlog.修 ...
- Android开发12——Andorid中操作数据库的insert的两种方法以及nullColumnHack
一.发现问题 先看两种方法插入数据 public void save(Person p){ SQLiteDatabase db = dbHelper.getWritableDatabase(); db ...
- PHP生成带logo图像二维码的两种方法
本文主要和大家分享PHP生成带logo图像二维码的两种方法,主要以文字和代码的形式和大家分享,希望能帮助到大家. 一.利用Google API生成二维码Google提供了较为完善的二维码生成接口,调用 ...
随机推荐
- Google Kickstart在线测试规则以及注意事项
谷歌招聘在如火如荼的进行中,进谷歌都需要经过谷歌kickstart在线测试,然后过了之后还有五轮的面试- -.好吧毕竟你待遇高,你强你有理.. 下面介绍一下进谷歌的第一关google kickstar ...
- scp命令的使用
scp命令是什么 scp是 secure copy的缩写, scp是linux系统下基于ssh登陆进行安全的远程文件拷贝命令. scp命令用法 scp [-1246BCpqrv] [-c cipher ...
- 使用git版本管理工具
1.(1)正常提交:git add 提交文件 git init //git init之后建立一个.gitignore可以避免node_modules这类文件夹提交 git add . git co ...
- 关于ButterKnife 设置全局配置
先在项目的根目录的build.grade添加:classpath'com.neenbedankt.gradle.plugins:android-apt:1.8' 然后在app build.grade ...
- SVNKit学习——svn二次开发背景和闲谈(一)
开发背景: 简述现有流程:代码的合并.提交是以任务为最小单元的.例如A和B两个同学开发不同的任务,那就是两个任务号.合并的时候可能会先合并A的代码,在合并B的代码. 需求:SVN合并程序开发——一款能 ...
- Siebel Tools配置
默认安装的Siebel+Tools,Tools登陆时有3个选项:Local.Sample.Server,具体涵义如下: Local:指本地数据库.按照Siebel开发建议,开发人员需要从Siebel ...
- [USACO17JAN]Subsequence Reversal
嘟嘟嘟 这题刚开始是什么思路也没有,关键是不知道怎么解决序列反转的问题. 然后我就想到如果暴力反转一个序列的话,实际上就是不断交换数组中的两个数ai和aj,同时要满足交换的数不能交叉. 然后又看了一眼 ...
- 记一次msfconsole_android渗透实验
1>查看本机IP 2>生成App木马 3>将生成的木马安装至手机 4>打开msfconsole 1, use exploit/multi/handler 加载模块. 2, ...
- JDK下载
1.进入Java官网,方式不限,如百度“Java 官网”,www.oracle.com,找到Java SE -> download.链接如下: http://www.oracle.com/tec ...
- ubuntu 网桥配置
vim /etc/network/interfaces auto lo iface lo inet loopback auto eth0 auto eth2 auto eth3 iface eth0 ...