1 请你仅使用两个队列实现一个后入先出( LIFO )的栈,并支持普通栈的全部四种操作( push 、 top 、 pop 和 empty )。
实现 MyStack 类:
- void push ( int x )将元素 x 压入栈顶。
- int pop ()移除并返回栈顶元素。
- int top ()返回栈顶元素。
- boolean empty ()如果栈是空的,返回 true ;否则,返回 false 。
注意:
- 你只能使用队列的基本操作 push to back 、 peek / pop from front 、 size 和 is empty 这些操作。
- 你所使用的语言也许不支持队列。你可以使用 list (列表)或者 deque (双端队列)来模拟一个队列,只要是标准的队列操作即可。
import java.util.LinkedList;
import java.util.Queue;
public class MyStack {
private Queue<Integer> qu1;
private Queue<Integer> qu2;
//构造方法
public MyStack(){
qu1=new LinkedList<>();
qu2=new LinkedList<>();//两个队列
}
public void push(int x){
if(!qu1.isEmpty()){
qu1.offer(x);//offer入队列
}else if(!qu2.isEmpty()){
qu2.offer(x);
}else{
//当两个队列都为空,放到第一个队列中
qu1.offer(x);
}
}
public int pop(){
if(empty()){
return -1;//两个队列都为空的时候,返回-1
}
if(!qu1.isEmpty()){
int size=qu1.size();
for(int i=0;i<size-1;i++){//弹出qu2中的要获得元素的之前的所有元素到qu1中
int x=qu1.poll();//poll弹出元素
qu2.offer(x);
}
//返回剩下的元素
return qu1.poll();
}else{
int size=qu1.size();
for(int i=0;i<size-1;i++){
int x=qu2.poll();
qu1.offer(x);
}
//返回剩下的元素
return qu2.poll();
}
}
//获取栈顶元素但是不删除
public int top(){
if(empty()){
return -1;//两个队列都为空的时候,返回-1
}
if(!qu1.isEmpty()){
int x=-1;
int size=qu1.size();
for(int i=0;i<size-1;i++){//弹出qu2中的要获得元素的之前的所有元素到qu1中
x=qu1.poll();//poll弹出元素
qu2.offer(x);//每弹一个元素在qu2中保存一下
}
//返回剩下的元素
return x;
}else{
int x=-1;
int size=qu2.size();
for(int i=0;i<size-1;i++){
x=qu2.poll();
qu1.offer(x);
}
//返回剩下的元素
return x;
}
}
//两个队列都为空的时候,整个栈为空(是否为空)
public boolean empty(){
if(qu1.isEmpty() && qu2.isEmpty()){
return true;
}
return false;
}
}
2 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作( push 、 pop 、 peek 、 empty ):
实现 MyQueue 类:
- void push ( int x )将元素 x 推到队列的末尾
- int pop ()从队列的开头移除并返回元素
- int peek ()返回队列开头的元素
- boolean empty ()如果队列为空,返回 true ;否则,返回 false
入队:统统放到第一个栈当中;
出队:每次都出第二个栈当中的元素,如果第二个栈为空,则把第一个栈当中的所有元素倒过来;
import java.util.Stack;
public class MyQueueLeetCode {
private Stack<Integer> stack1;
private Stack<Integer> stack2;//需要两个栈
public MyQueueLeetCode(){
this.stack1=new Stack<>();
this.stack2=new Stack<>();
}
public void push(int x){
stack1.push(x);
}
//弹出对头元素
public int pop(){
if(empty()){
return -1;
}
if(stack2.empty()){
while (!stack1.empty()){
int val=stack1.pop();
stack2.push(val);//弹出stack1中的元素,放到stack2中
}
}
//第二个栈不为空
return stack2.pop(); //弹出第二个栈中的所有的元素
}
//获取对头元素
public int peek(){
if(empty()){
return -1;
}
if(stack2.empty()){
while (!stack1.empty()){
int val=stack1.pop();
stack2.push(val);//弹出stack1中的元素,放到stack2中
}
}
//第二个栈不为空
return stack2.peek();
}
//判断队列是否为空
public boolean empty(){
return stack1.empty() && stack2.empty();
}
}
3 设计一个支持 push , pop , top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
- MinStack ()初始化堆栈对象。
- void push ( int val )将元素 val 推入堆栈。
- void pop ()删除堆栈顶部的元素。
- int top ()获取堆栈顶部的元素。
- int getMin ()获取堆栈中的最小元素。
import java.util.Stack;
public class MinStack {
private Stack<Integer> stack;
private Stack<Integer> minStack;
public MinStack(){
this.stack=new Stack<>();
this.minStack =new Stack<>();
}
public void push(int val){
stack.push(val);
if(minStack.empty()){
minStack.push(val);
}else{
int x=minStack.peek();
if(x>=val){//必须有等号
minStack.push(val);
}
}
}
public void pop(){
if(stack.empty()){
return;
}
int x=stack.pop();//x等于栈顶元素
//每次弹出元素时,都需要和最小栈的栈顶元素进行比较
if(x==minStack.peek()){//x与minStack的栈顶元素进行比较
minStack.pop();//若相等则minStack的栈顶元素也弹出
}
}
//获取普通的栈的栈顶元素
public int top(){
if(stack.empty()){
return -1;
}
return stack.peek();
}
//获取当前栈的最小的元素
public int getMin(){
if(minStack.empty()){
return -1;
}
return minStack.peek();
}
}