实现一个最小栈,有三种操作,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输出弹出的元素。
7 1 3 1 4 0 1 2 0 2 0
3 2 2 3
第一个操作为push 3,此时栈元素为3
第二个操作为push 4,此时栈元素为3,4
第三个操作为min,此时栈元素为3,4,输出最小值3
第四个操作为push 2,此时栈元素为3,4,2
第五个操作为min,此时栈元素为3,4,2,输出最小值2
第六个操作为pop,弹出元素2,此时栈元素为3,4,输出弹出的元素2
第七个操作为min,此时栈元素为3,4,输出最小值3
您的代码已保存 运行超时:您的程序未能在规定时间内运行结束,请检查是否循环有错或算法复杂度过大。 case通过率为66.67%
可以用的方法都用了:
法1:
一个栈记录差值:这个方法所有操作都是O(1)根本不需要格外的辅助空间
法2:
使用一个辅助栈,记录最小值,所有操作也是O(1)
上述方法都使用过后,通过率都是66.67%
开始怀疑人生!
于是对第二种方法做了点点优化,通过数组手写一个栈(代码如下)
import java.util.*;
class MinStack{
int[] array;
int[] minArray;
int index;
public MinStack(int capacity){
array=new int[capacity+5];
minArray=new int[capacity+5];
index=0;
minArray[0]=Integer.MAX_VALUE;
}
public void push(int elem){
array[++index]=elem;
minArray[index]=Math.min(elem,minArray[index-1]);
}
public int pop(){
index--;
return array[index+1];
}
public int min(){
return minArray[index];
}
}
public class Main{
public static void main(String[] args){
MinStack minStack;
int Q,op;
Scanner in=new Scanner(System.in);
Q=in.nextInt();
minStack=new MinStack(Q);
while(Q-->0){
op=in.nextInt();
if(op==0){
System.out.println(minStack.min());
}else if(op==1){
minStack.push(in.nextInt());
}else if(op==2){
System.out.println(minStack.pop());
}
}
}
}没错,这次优化依旧没有什么*用,通过率还是66.67%
算了,思想了解了,不死磕!
#include <bits/stdc++.h>
using namespace std;
int main()
{
int q,op,x;
cin>>q;
stack<int>s1,s2;
while(q--)
{
cin>>op;
if(op==0)
cout<<s2.top()<<endl;
else if(op==1)
{
cin>>x;
s1.push(x);
if(s2.empty() || x <= s2.top())
s2.push(x);
}
else if(op==2)
{
cout<<s1.top()<<endl;
if(s1.top() == s2.top())
s2.pop();
s1.pop();
}
}
return 0;
}
/*
空间换时间,另设一个栈b记录最小值
*/
#include <bits/stdc++.h>
using namespace std;
stack<int> a, b;
int main()
{
//freopen("input.txt", "r", stdin);
int t, op, x;
cin >> t;
while(t--) {
scanf("%d", &op);
if(op == 1) {
scanf("%d", &x);
a.push(x);
if(!b.empty()) b.push(min(b.top(), x));
else b.push(x);
} else if (op == 2) {
printf("%d\n", a.top());
a.pop();
b.pop();
} else {
printf("%d\n", b.top());
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int main(){
int Q, op, x;
cin>>Q;
stack<int> S, S_min;
while(Q--){
cin>>op;
if(op==0)
cout<<S_min.top()<<endl;
else if(op==1){
cin>>x;
S.push(x);
if(S_min.empty() || x<=S_min.top())
S_min.push(x);
}else if(op==2){
cout<<S.top()<<endl;
if(S.top() == S_min.top())
S_min.pop();
S.pop();
}
}
return 0;
} #include <stdio.h>
#include <iostream>
using namespace std;
struct Stack {
int *a;
int *Min;
int index;
int mindex;
Stack(int n) {
a = new int [n + 1];
Min = new int [n + 1];
index = 0;
mindex = 0;
for (int i = 0; i < n; i++) {
Min[i] = (int)1e9 + 10;
}
}
~Stack() {
delete []a;
delete []Min;
}
void push(int val) {
if (val <= Min[mindex]) {
Min[++mindex] = val;
}
a[++index] = val;
}
int pop() {
int temp = a[index];
index--;
if (temp == Min[mindex]) {
mindex--;
}
return temp;
}
int query() {
return Min[mindex];
}
};
const int N = (int)5e5 + 10;
int main() {
Stack st(N);
int tt;
scanf("%d", &tt);
while (tt--) {
int op;
scanf("%d", &op);
if (op == 1) {
int val;
scanf("%d", &val);
st.push(val);
} else if (op == 0) {
printf("%d\n", st.query());
} else {
printf("%d\n", st.pop());
}
}
return 0;
} import java.util.Scanner;
import java.util.Stack;
class MinStack{
// 最小栈,存入栈中的元素的一个数组,长度为2,一个是入栈的元素,另一个是之前入栈内的最小元素
//数组栈, [当前值, 当前最小值]
private Stack<int[]> stack = new Stack<>();
// 构造方法
public MinStack(){};
// push方法
public void push(int val){
if(stack.isEmpty()){
stack.push(new int[]{val, val});
}else{
stack.push(new int[]{val, Math.min(val, stack.peek()[1])});
}
}
// pop方法
public int pop(){
return stack.pop()[0];
}
// getMin方法
public int getMin(){
return stack.peek()[1];
}
}
// https://www.nowcoder.com/practice/a4d17eb2e9884359839f8ec559043761
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int Q, op;
Q = in.nextInt();
MinStack minStack = new MinStack();
for(int i = 0; i < Q; i++){
op = in.nextInt();
if(op == 0){
System.out.println(minStack.getMin());
}else if(op == 1){
minStack.push(in.nextInt());
}else if(op == 2){
System.out.println(minStack.pop());
}
}
}
} import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Stack;
class MinStack {
private Stack<Integer> stack = new Stack<>();
private Stack<Integer> minStack = new Stack<>();
public void push(int val) {
stack.push(val);
if(minStack.isEmpty()){
minStack.push(val);
}else{
if(val < minStack.peek())
minStack.push(val);
else
minStack.push(minStack.peek());
}
}
public int pop() {
minStack.pop();
return stack.pop();
}
public int min() {
return minStack.peek();
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
MinStack stack = new MinStack();
int n = Integer.parseInt(br.readLine().trim());
for(int i = 0; i < n; i++){
String[] params = br.readLine().trim().split(" ");
int op = Integer.parseInt(params[0]);
if(op == 0){
System.out.println(stack.min());
}else if(op == 2){
System.out.println(stack.pop());
}else
stack.push(Integer.parseInt(params[1]));
}
}
} #include<iostream>
#include<stack>
using namespace std;
class Solution{
public:
int getmin(){
return op2.top();
}
void push(int x){
if(op1.empty()){
op1.push(x);
op2.push(x);
}else{
op1.push(x);
if(x <= op2.top())
op2.push(x);
}
}
void pop(){
if(!op1.empty()){
int tmp = op1.top();
if(tmp == op2.top())
op2.pop();
op1.pop();
cout << tmp << endl;
}
}
private:
stack<int> op1;
stack<int> op2;
};
int main()
{
Solution a;
int x;
cin >> x;
while(x--){
int op;
cin >> op;
if(op == 0){
cout << a.getmin() << endl;
}else if(op == 2){
a.pop();
}else if(op == 1){
int t;
cin >> t;
a.push(t);
}
}
return 0;
} import java.io.*;
import java.util.*;
/**
* <a href="https://www.nowcoder.com/questionTerminal/a4d17eb2e9884359839f8ec559043761">
* 最小栈</a>
*
* @author EdwardLee03
* @since 2020-03-22
*/
public class Main {
private static class StackElement {
/**
* 值
*/
int value;
/**
* 最小值
*/
int min;
}
/** 值栈 */
private Deque<StackElement> deque;
public Main() {
deque = new LinkedList<>();
}
public void push(int x) {
StackElement se = new StackElement();
se.value = x;
if (deque.isEmpty() || deque.peekFirst().min >= x) {
se.min = x;
} else {
se.min = deque.peekFirst().min;
}
deque.offerFirst(se);
}
public int pop() {
if (deque.isEmpty()) {
return 0;
}
return deque.pollFirst().value;
}
public int min() {
if (deque.isEmpty()) {
return 0;
}
return deque.peekFirst().min;
}
public static void main(String[] args) throws IOException {
Main minStack = new Main();
StreamTokenizer streamTokenizer = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
streamTokenizer.nextToken();
int lineNum = (int) streamTokenizer.nval;
// 通过缓冲器优化IO输出打印
StringBuilder sb = new StringBuilder(lineNum * 4);
while (lineNum-- > 0) {
streamTokenizer.nextToken();
int op = (int) streamTokenizer.nval;
switch (op) {
case 1:
streamTokenizer.nextToken();
int e = (int) streamTokenizer.nval;
minStack.push(e);
break;
case 0:
sb.append(minStack.min()).append('\n');
break;
case 2:
sb.append(minStack.pop()).append('\n');
break;
}
}
System.out.println(sb.toString().trim());
}
}
/*40%,在哪里会数组越界,求解答*/
import java.util.*;
class minStack{
public Stack<Integer> stack = new Stack<Integer>();
public Stack<Integer> min = new Stack<Integer>();
public int minval = 0;
public int pop(){
int k = 0;
if(!stack.isEmpty()){
k=stack.pop();
min.pop();
minval = min.peek();
return k;
}
else{
return -1;
}
}
public void push(int val){
if(stack.isEmpty()){
minval = val;
}else{
if(val<minval){
minval = val;
}
}
stack.push(val);
min.push(minval);
}
public int getMin(){
if(!stack.isEmpty()){
return min.peek();
}else{
return -1;
}
}
}
public class Main{
public static void main(String[] args){
minStack mmm = new minStack();
Scanner sc = new Scanner(System.in);
int Q= sc.nextInt();
int k = 0;
int m = 0;
for(int i = 0;i<Q;i++){
sc.nextLine();
k = sc.nextInt();
if(k == 0){
System.out.println(mmm.getMin());
}
if(k == 1){
m = sc.nextInt();
mmm.push(m);
}
if(k == 2){
System.out.println(mmm.pop());
}
}
}
} class MinStack{
public:
MinStack()
{
minNum = 0x7fffffff;
}
void push(int val)
{
if(val <= minNum){
stk.push(minNum);
minNum = val;
}
stk.push(val);
}
int pop(void)
{
int val = stk.top();
stk.pop();
if(val == minNum){
minNum = stk.top();
stk.pop();
}
return val;
}
int min(void)
{
return minNum;
}
private:
stack<int, vector<int> > stk;
int minNum;
};
int main(void)
{
int q , opCode = 0, opVal = 0;
MinStack stk;
cin >> q;
while(q-- > 0)
{
cin >> opCode;
switch(opCode)
{
case 0:
cout << stk.min() << endl;
break;
case 1:
cin >> opVal;
stk.push(opVal);
break;
case 2:
cout << stk.pop() << endl;
break;
}
}
} class MyStack: def __init__(self): self.st_data = [] self.st_min = [] def push(self, node): self.st_data.append(node) if not self.st_min or node < self.st_min[-1]: self.st_min.append(node) else: self.st_min.append(self.st_min[-1]) def pop(self): self.st_min.pop() return self.st_data.pop() def get_min(self): return self.st_min[-1] st = MyStack() Q = input() for i in range(Q): #lst = input().split() #op = int(lst[0]) op = raw_input() if op == "0": print(st.get_min()) elif op == "2": print(st.pop()) else: st.push(int(op[2:]))
#include <iostream>
#include <stack>
using namespace std;
stack<int> stack1,stack2;
void push(int value)
{
stack1.push(value);
if(stack2.empty())
stack2.push(value);
else if(value<=stack2.top())
stack2.push(value);
}
int pop()
{
if(stack1.top()==stack2.top())
stack2.pop();
int res=stack1.top();
stack1.pop();
return res;
}
int min()
{
return stack2.top();
}
int main()
{
int Q;
cin >>Q;
for(int i=0;i<Q;i++)
{
int op,x;
cin>>op;
if(op==0&& !stack1.empty())
cout<<min()<<endl;
if(op==1)
{
int x;
cin >>x;
push(x);
}
if(op==2&& !stack1.empty())
cout<<pop()<<endl;
}
return 0;
} #include<iostream>
#include<stack>
#include<vector>
using namespace std;
int main() {
stack<int> stack1;
stack<int> stack2;
int Q;
cin >> Q;
int** a = new int*[Q];
for (int i = 0; i < Q; i++)
a[i] = new int[2];
for (int i = 0; i < Q; i++)
for (int j = 0; j < 2; j++)
a[i][j] = 0;
for (int i = 0; i < Q; i++)
{
cin >> a[i][0];
if (a[i][0] == 1)
cin >> a[i][1];
}
//
for (int i = 0; i < Q; i++)
{
//push
if (a[i][0] == 1)
{
stack1.push(a[i][1]);
if (!stack2.empty())
{
if(a[i][1] <= stack2.top())
stack2.push(a[i][1]);
}
else
stack2.push(a[i][1]);
}
//pop
else if (a[i][0] == 2)
{
int tmp = stack1.top();
if (tmp == stack2.top())
stack2.pop();
stack1.pop();
cout << tmp << endl;
}
//min
else
{
int min = stack2.top();
cout << min << endl;
}
}
return 0;
} #include<iostream>
#include<stack>
using namespace std;
class MinStack{
public:
MinStack(){}
void push(int value){
_sss.push(value);
if(_min.empty() || _min.top() > value)
_min.push(value);
}
int pop(){
if(_min.top() == _sss.top())
_min.pop();
int num = _sss.top();
_sss.pop();
return num;
}
int min(){
return _min.top();
}
private:
stack<int> _sss;
stack<int> _min;
};
int main(){
int Q = 0;
MinStack s;
cin >> Q;
for(int i = 0;i < Q;++i){
int op = 0;
cin >> op;
if (op == 0) {
cout << s.min() << endl;
}
else if (op == 1)
{
int op2 = 0;
cin >> op2;
s.push(op2);
}
else if (op == 2)
{
cout << s.pop() << endl;
}
}
return 0;
} #include <iostream>
#include <stack>
using namespace std;
class ministack
{
private:
stack<int> sdata;
stack<int> sass;
public:
void push(int value)
{
if(sdata.empty())
{
sdata.push(value);
sass.push(value);
}
else
{
int mini = sass.top();
if(value<mini)
{
sass.push(value);
}
else
{
sass.push(mini);
}
sdata.push(value);
}
}
int pop()
{
if(!sdata.empty())
{
int data = sdata.top();
sdata.pop();
sass.pop();
return data;
}
}
int min()
{
if(!sdata.empty())
{
return sass.top();
}
}
};
int main()
{
int times =0;
cin>>times;
ministack m;
for(int i =0;i<times;i++)
{
int op;
cin>>op;
if(op==0)
{
cout<<m.min()<<endl;
}
if(op==1)
{
int data;
cin>>data;
m.push(data);
}
if(op==2)
{
cout<<m.pop()<<endl;;
}
}
return 0;
}