题目
题目描述
实现一个最小栈,有三种操作,min:得到栈中的最小值,push:在栈顶插入一个元素,pop:弹出栈顶元素,使这三种操作的时间复杂度都是O(1)
要求:语言不限
输入描述:
第一行是一个数Q,接下来Q行每行表示一个操作,每行首先是操作op
若op = 0,则输出当前栈中的最小值;
若op = 1,表示push,接着正整数x,把在x放进栈顶;
若op = 2,表示pop,弹出栈顶元素
保证Q<=500000,保证op = 0或2时(即min操作和pop操作时)栈不为空。
你可以假设一开始栈的空的。
输出描述:
对应每个op = 0或2,如果是op = 0输出当前栈中的最小值,如果是op = 2输出弹出的元素。
示例1
输入:
7
1 3
1 4
0
1 2
0
2
0
输出:
3
2
2
3
分析
引入一个最小值栈minStack,储存当前栈stack中最小的元素。需要修改原来栈的push() 和pop() 操作。
- 对于原来栈stack的push() 操作,每次push进一个元素x之前,要对比它和最小值栈minStack的栈顶元素的大小,若 x<=stack.peek(),则将x也要push进最小值栈中。
- 对于原来栈stack的pop()操作,每次pop出一个元素x之前,也要对比x和最小值栈minStack的栈顶元素大小,若 x==stack.peek(),则将最小值栈minStack也执行pop操作;
- 返回最小值,即返回minStack.peek()。
代码
/*
引入一个存放当前栈中的最小值的栈;
每次push进去新值后,都要和当前最小值比较,若小于等于最小值,则将它push进最小值栈;
每次pop操作后,也要和当前最小值比较,若和最小值相等,则对最小值栈进行pop操作。
*/
import java.util.Stack;
import java.util.Scanner;
public class Main{
public static Stack<Integer> minStack = new Stack<>();
public static Stack<Integer> stack = new Stack<>();
public static int getMin(){
return minStack.peek();
}
public static void push(int x){
stack.push(x);
if(minStack.isEmpty() || x <= minStack.peek()){
minStack.push(x);
}
}
public static int pop(){
if(stack.peek() == minStack.peek()){
minStack.pop();
}
return stack.pop();
}
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
int q = sc.nextInt();
for(int i=0; i<q; i++){
sc.nextLine();
int op = sc.nextInt(); //操作
switch(op){
case(1):
push(sc.nextInt());
//System.out.println(getMin());
continue;
case(2):
System.out.println(pop());
continue;
case(0):
System.out.println(getMin());
continue;
}
}
sc.close();
}
}
存在问题
因为是用java写的,所以当输入数据过大时,时间复杂度还是太高了,最后执行通过率只有53.3%。希望之后再改进,但思路是没问题的。
运行结果
输入有10000行数据时: