实现一个最小栈,有三种操作,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; }