剑指 Offer 09. 用两个栈实现队列
思路:
题目已经告诉我们要用两个栈去实现队列,我们假设现在有两个栈A,B
如果此时入队了两个元素,先把他添加到A里去,现在有两种操作
- 入队: 入队直接把他放在A里即可
- 出队: 因为队列要满足先入先出,我们可以把值从A中pop,再push进B,此时B的栈顶就是下一个待出的元素了,弹出栈顶后,B内还剩下一个元素便是下一次需要出队的 因此,我们可以在每次出队时,检查B内还有没有元素,有就popB,反之将A的元素移动到B,再次popB即可
class CQueue {
public:
stack<int> s1,s2;
CQueue() {}
void appendTail(int value) {
s1.push(value);
}
int deleteHead() {
if(!s2.size()){
if(!s1.size()) return -1;
while(s1.size()){
s2.push(s1.top());
s1.pop();
}
}
int t=s2.top();
s2.pop();
return t;
}
};
class CQueue {
Stack<Integer> A=new Stack<>();
Stack<Integer> B=new Stack<>();
public CQueue() {}
public void appendTail(int value) {
A.add(value);
}
public int deleteHead() {
if(B.size()==0){
if(A.size()==0){
return -1;
}
while(!A.empty()){
B.add(A.peek());
A.pop();
}
}
int ans=B.peek();
B.pop();
return ans;
}
}
剑指 Offer 30. 包含min函数的栈
思路:
考虑下边一个场景: +是入栈,-是出栈 +2+1+2+2---- 在1,2,2入栈后,后边的2对答案已经没有任何贡献了,因为在1出栈前,后边的2不可能是答案,然而如果1出栈了,后边的2必然早就出栈了(先入后出) 但是第一个2对答案有贡献吗?有,假如1也出栈了,那么答案就是2了
按照这个思路,我们可以设置如下算法,建立两个栈A,B; A用来存储真实数据,B是非单调递增栈,A正常进行push,pop操作, 在Apush时,B检查当前元素是否比栈顶小或等于,是的话,B也push,在Apop时,B检查pop掉的元素是不是自己栈顶的元素,是的话也进行pop min方法直接返回B栈顶元素即可
class MinStack {
public:
/** initialize your data structure here. */
stack<int> A,B;
MinStack() {}
void push(int x) {
A.push(x);
if(!B.size()||x<=B.top()) B.push(x);
}
void pop() {
if(A.top()==B.top()) B.pop();
A.pop();
}
int top() {
return A.top();
}
int min() {
return B.top();
}
};
/*
class MinStack {
public:
stack<int> A,B;
MinStack() {}
void push(int x) {
A.push(x);
if(!B.size()||x<=B.top()) B.push(x);
}
void pop() {
if(A.top()==B.top()) B.pop();
A.pop();
}
int top() {
return A.top();
}
int min() {
return B.top();
}
};
*/
class MinStack {
Stack<Integer> A=new Stack<>();
Stack<Integer> B=new Stack<>();
public MinStack() {}
public void push(int x) {
A.push(x);
if(B.empty()||x<=B.peek()) B.push(x);
}
public void pop() {
if(A.peek().equals(B.peek())) B.pop();
A.pop();
}
public int top() {
return A.peek();
}
public int min() {
return B.peek();
}
}