用栈实现队列
方法一
一个栈用来放数据,一个栈用来取数据
push:O(1)
pop:最好O(1),最坏O(n)
class MyQueue {
private Stack<Integer> stack1=new Stack<>();
private Stack<Integer> stack2=new Stack<>();
public void push(int x) {
stack1.push(x);
}
public int pop() {
if(!stack2.empty()){
return stack2.pop();
}
while (!stack1.empty()){
stack2.push(stack1.pop());
}
return stack2.pop();
}
public int peek() {
if(!stack2.empty()){
return stack2.peek();
}
while (!stack1.empty()){
stack2.push(stack1.pop());
}
return stack2.peek();
}
public boolean empty() {
return stack1.empty()&&stack2.empty();
}
}
方法二
一个栈用来存数据,一个栈用来倒腾数据
push():时间复杂度O(n)
pop():时间复杂度O(1)
1、2、3的插入过程
![](https://img-blog.csdnimg.cn/img_convert/a178c72a8e8c59a293a339182854d0fe.png)
class MyQueue {
private Stack<Integer> stack1=new Stack<>();
private Stack<Integer> stack2=new Stack<>();
public void push(int x) {
while (!stack1.isEmpty()){
stack2.add(stack1.pop());
}
stack2.add(x);
while (!stack2.isEmpty()){
stack1.add(stack2.pop());
}
}
public int pop() {
return stack1.pop();
}
public int peek() {
return stack1.peek();
}
public boolean empty() {
return stack1.empty();
}
}
用队列实现栈
方法一
一个队列用来存数据,一个队列用来倒腾数据
push():时间复杂度O(n)
pop():时间复杂度O(1)
class MyStack {
private Queue<Integer> queue1 = new ArrayDeque<>();
private Queue<Integer> queue2 = new ArrayDeque<>();
public void push(int x) {
while (!queue1.isEmpty()){
queue2.offer(queue1.poll());
}
queue1.offer(x);//插入到queue中,即后进先出
while (!queue2.isEmpty()){
queue1.offer(queue2.poll());
}
}
public int pop() {
return queue1.poll();
}
public int top() {
return queue1.peek();
}
public boolean empty() {
return queue1.isEmpty();
}
}
方法二
一个队列用来放数据
取数据是将一个队列除队尾外的数据转移到另一个队列中,并交换两个队列
push():时间复杂度O(1)
pop():时间复杂度O(n)
class MyStack {
private Queue<Integer> queue1 = new ArrayDeque<>();
private Queue<Integer> queue2 = new ArrayDeque<>();
private int top;//为了取数据方便,用一个值来记录栈顶元素
public void push(int x) {
queue1.offer(x);
top=x;
}
public int pop() {
int nowTop=-1;
int preTop=this.top;
while (queue1.size()>1){
nowTop=queue1.poll();
queue2.offer(nowTop);
}
queue1.poll();
Queue<Integer> temp=queue1;
queue1=queue2;
queue2=temp;
this.top=nowTop;
return preTop;
}
public int top() {
return this.top;
}
public boolean empty() {
return queue1.isEmpty();
}
}
方法三
一个队列,添加元素时,先队列中之前的元素依次移到刚添加的元素的后面
push():时间复杂度O(n)
pop():时间复杂度O(1)
class MyStack {
private Queue<Integer> queue = new ArrayDeque<>();
public void push(int x) {
queue.offer(x);
for (int i = 1; i <queue.size() ; i++) {
queue.add(queue.poll());
}
}
public int pop() {
return queue.poll();
}
public int top() {
return queue.peek();
}
public boolean empty() {
return queue.isEmpty();
}
}
最小栈
能在常数时间内获得最小元素
用一个辅助栈存以该位置为栈顶时的最小元素
class MinStack {
private Stack<Integer> stack = new Stack<>();
private Stack<Integer> minStack = new Stack<>();
int min = Integer.MAX_VALUE;
public void push(int x) {
stack.push(x);
if (x < min) {
min = x;
minStack.push(x);
} else {
minStack.push(min);
}
}
public void pop() {
stack.pop();
if (min == minStack.pop()) {
//考虑栈为空的情况
if(!minStack.isEmpty()){
min = minStack.peek();
} else{
min=Integer.MAX_VALUE;
}
}
}
public int top() {
return stack.peek();
}
public int getMin() {
return min;
}
}
空间优化:
只有加入的元素比之前的最小值更小,才将当前最小值放入辅助栈中,避免了存一些无用的值
public void push(int x) {
stack.push(x);
//要考虑=
if (x <= min) {
min = x;
minStack.push(x);
}
}
public void pop() {
Integer num = stack.pop();
if(num==min){
minStack.pop();
}
//考虑栈为空的情况
if (!stack.isEmpty()) {
min = minStack.peek();
} else{
min=Integer.MAX_VALUE;
}
}