在做这道题前,我们需要有 栈 的先驱知识,可以参考本人的这篇博客
(41条消息) 【数据结构】栈_Living_Amethyst的博客-CSDN博客
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
- void push(int x) 将元素 x 压入栈顶。
- int pop() 移除并返回栈顶元素。
- int top() 返回栈顶元素。
- boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
分析:
由于队列的特点是“先进先出”,而栈的特点是“后入先出”,所以用队列实现栈 仅用一个队列是不能实现的,需要两个队列
我们的思路是:入的时候都入到不为空的队列里,出的时候就把不为空的队列里的除了要出的元素之外的其他(size-1)个元素都移到为空的队列里
- import java.util.LinkedList;
- import java.util.Queue;
-
- class MyStack {
- private Queue<Integer> qu1;
- private Queue<Integer> qu2;
-
- public MyStack() {
- qu1 = new LinkedList<>();
- qu2 = new LinkedList<>();
- }
-
- /**
- * 入到不为空的队列中
- * 如果都为空,就入到qu1中
- * @param x
- */
- public void push(int x) {
- if(!qu1.isEmpty()){
- qu1.offer(x);
- }else if(qu2.isEmpty()){
- qu2.offer(x);
- }else{
- qu1.offer(x);
- }
- }
-
- public int pop() {
- //1.判断当前“栈”是否为空
- if(empty()){
- return -1;
- }
- if(!qu1.isEmpty()){
- //从不为空的队列里出 size-1 个元素
- int size = qu1.size();
- for (int i = 0; i < size-1; i++) {
- /*
- int tmp = qu1.poll();
- qu2.offer(tmp);
- */
- qu2.offer(qu1.poll());
- }
- return qu1.poll();
- }else{
- //从不为空的队列里出 size-1 个元素
- int size = qu2.size();
- for (int i = 0; i < size-1; i++) {
- /*
- int tmp = qu1.poll();
- qu2.offer(tmp);
- */
- qu1.offer(qu2.poll());
- }
- return qu2.poll();
- }
- }
-
- public int top() {
- //1.判断当前“栈”是否为空
- if(empty()){
- return -1;
- }
- if(!qu1.isEmpty()){
- //从不为空的队列里出 size个元素
- int size = qu1.size();
- int tmp = -1;
- for (int i = 0; i < size; i++) {
- tmp = qu1.poll();
- qu2.offer(tmp);
- }
- return tmp;
- }else{
- //从不为空的队列里出 size个元素
- int size = qu2.size();
- int tmp = -1;
- for (int i = 0; i < size; i++) {
- tmp = qu2.poll();
- qu1.offer(tmp);
- }
- return tmp;
- }
-
- }
-
- public boolean empty() {
- if (qu1.isEmpty() && qu2.isEmpty()) {
- return true;
- }
- return false;
-
- }
- }
请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
- void push(int x) 将元素 x 推到队列的末尾
- int pop() 从队列的开头移除并返回元素
- int peek() 返回队列开头的元素
- boolean empty() 如果队列为空,返回 true ;否则,返回 false
分析:和上一题类似,若要用栈实现队列,我们需要两个栈
- import java.util.Stack;
- class MyQueue {
- private Stack<Integer> s1;
- private Stack<Integer> s2;
-
- public MyQueue() {
- s1 = new Stack<>();
- s2 = new Stack<>();
- }
-
- public void push(int x) {
- //入队的逻辑是把元素统一放到第一个栈中
- s1.push(x);
- }
- //如果第二个栈不为空,则出栈顶元素,否则把第一个栈的元素全部导入第二个栈
- public int pop() {
- if(empty()){
- return -1;//两个栈都是空
- }
- if (s2.empty()){
- //把第一个栈的元素全部导入第二个栈
- while(!s1.empty()){
- s2.push(s1.pop());
- }
- }
- //s2一定是不为空的
- return s2.pop();
- }
-
- public int peek() {
- if(empty()){
- return -1;//两个栈都是空
- }
- if (s2.empty()){
- //把第一个栈的元素全部导入第二个栈
- while(!s1.empty()){
- s2.push(s1.pop());
- }
- }
- //s2一定是不为空的
- return s2.peek();
- }
-
- public boolean empty() {
- return s1.empty() && s2.empty();
- }
- }
设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
- MinStack() 初始化堆栈对象。
- void push(int val) 将元素val推入堆栈。
- void pop() 删除堆栈顶部的元素。
- int top() 获取堆栈顶部的元素。
- int getMin() 获取堆栈中的最小元素。
分析:
- import java.util.Stack;
- class MinStack {
- private Stack<Integer> s1;
- private Stack<Integer> minStack;
- public MinStack() {
- s1 = new Stack<>();
- minStack = new Stack<>();
- }
-
- public void push(int val) {
- s1.push(val);//s1这个栈是一定会放元素的
- if(minStack.empty()){
- minStack.push(val);
- }else{
- int x = minStack.peek();
- if(val <= x){ //这里必须加等号
- minStack.push(val);
- }
- }
- }
- public void pop() {
- int x = s1.pop();
- int x2 = minStack.peek();
- if(x == x2){
- minStack.pop();
- }
- }
-
- //获取当前栈顶元素不删除
- public int top() {
- return s1.peek();
- }
-
- public int getMin() {
- return minStack.peek();
- }
- }