0
点赞
收藏
分享

微信扫一扫

【大厂算法笔试题 | 11】用栈实现队列、用队列实现栈系列问题


文章目录

  • ​​总述​​
  • ​​一、以O(1)的时间复杂度获取栈中最小元素​​
  • ​​方法一​​
  • ​​1、思路​​
  • ​​2、代码​​
  • ​​方法二​​
  • ​​1、思路​​
  • ​​2、代码​​
  • ​​二、用两个栈构建出一个队列​​
  • ​​1、思路​​
  • ​​2、代码​​
  • ​​3、测试​​
  • ​​三、用两个队列构建出一个栈​​
  • ​​1、思路​​
  • ​​2、代码​​
  • ​​3、测试​​

总述

有些面试官喜欢让你用栈实现BFS、用队列实现DFS,其实就是间接让你用栈实现队列、用队列实现栈;千万不要死脑筋想着就用一个栈实现队列、用一个队列实现栈;往往都是需要用两个栈实现一个队列,用两个队列实现一个栈。

一、以O(1)的时间复杂度获取栈中最小元素

实现一个栈,在基本功能的基础上,实现返回栈中最小元素的功能;要求以O(1)的时间复杂度获取到栈中的最小元素。

方法一

1、思路

第一种push的方式,当要push的数字 不大于 最小栈中的栈顶数字时,才将数字放入到最小栈;

第一种pop的方式,当要pop的数字 等于 最小栈中的栈顶数字时,才将数字pop出最小栈;

2、代码

public class Main {

private Stack<Integer> dataStack;

private Stack<Integer> minStack;

public Main() {
dataStack = new Stack<>();
minStack = new Stack<>();
}

public void push(Integer num) {
// 要push的数字 不大于 最小栈中的栈顶数字,则将数字放入到最小栈
if (minStack.isEmpty() || num <= getMin()) {
minStack.push(num);
}
dataStack.push(num);
}

public Integer pop() {
if (dataStack.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
Integer value = dataStack.pop();
if (value == getMin()) {
minStack.pop();
}
return value;
}

public Integer getMin() {
return minStack.peek();
}
}

方法二

1、思路

第二种push的方式,每次push时将 要push的数字 和 最小栈中的栈顶数字 中的最小值 push到最小栈。

第二种pop的方式,每次pop时,最小栈也同步pop。

2、代码

public class Main {

private Stack<Integer> dataStack;

private Stack<Integer> minStack;

public Main() {
dataStack = new Stack<>();
minStack = new Stack<>();
}

public void push(Integer num) {
// 要push的数字 不大于 最小栈中的栈顶数字,则将数字放入到最小栈
if (minStack.isEmpty() || num < getMin()) {
minStack.push(num);
} else {
int currMin = minStack.peek();
minStack.push(currMin);
}
dataStack.push(num);
}

public Integer pop() {
if (dataStack.isEmpty()) {
throw new RuntimeException("Stack is empty!");
}
minStack.pop();
return dataStack.pop();
}

public Integer getMin() {
return minStack.peek();
}
}

二、用两个栈构建出一个队列

使用栈设计一个队列结构

1、思路

栈:FILO,队列:FIFO

一个栈用于push,一个栈用于pop栈;提供一个函数pushToPop()当pushStack 不为空,popStack为空时,将push栈的数据全部反转放到pop栈;每次push、pop、peek是都调用函数pushToPop()。

2、代码

public class Main {

private Stack<Integer> pushStack;

private Stack<Integer> popStack;

public Main() {
pushStack = new Stack<>();
popStack = new Stack<>();
}

public void enqueue(int val) {
pushStack.push(val);
pushToPop();
}

public int dequeue() {
if (popStack.empty() && pushStack.empty()) {
throw new RuntimeException("queue is empty!");
}
pushToPop();
return popStack.pop();
}

public int peek() {
if (popStack.empty() && pushStack.empty()) {
throw new RuntimeException("queue is empty!");
}
pushToPop();
return popStack.peek();
}

public void pushToPop() {
// 如果popStack不为空时,直接将pushStack中的数据放到popStack中,会导致数据错乱
if (popStack.isEmpty()) {
while (!pushStack.empty()) {
popStack.push(pushStack.pop());
}
}
}
}

3、测试

public static void main(String[] args) {
Main test = new Main();
test.enqueue(1);
test.enqueue(2);
test.enqueue(3);
System.out.println(test.peek());
System.out.println(test.dequeue());
System.out.println(test.peek());
System.out.println(test.dequeue());
System.out.println(test.peek());
System.out.println(test.dequeue());
}

【大厂算法笔试题 | 11】用栈实现队列、用队列实现栈系列问题_时间复杂度

三、用两个队列构建出一个栈

使用队列设计一个栈结构;

1、思路

一个队列用于存放数据,一个队列作为辅助队列;

当要从队列中取一个数据时,将数据队列中的数据只留一个,其余全部移动到辅助队列,数据队列中保留的一个数据作为结果返回;最后再将辅助队列 和 数据队列 交换,供下一次存数据、 取数据使用。

2、代码

public class Main {

private Queue<Integer> queue;

private Queue<Integer> help;

public Main() {
this.queue = new LinkedList<>();
this.help = new LinkedList<>();
}

public void push(int val) {
queue.offer(val);
}

public int pop() {
while (queue.size() > 1) {
help.offer(queue.poll());
}
Integer res = queue.poll();
Queue<Integer> temp = queue;
queue = help;
help = temp;
return res;
}

public int peek() {
while (queue.size() > 1) {
help.offer(queue.poll());
}
Integer res = queue.poll();
help.offer(res);
Queue<Integer> temp = queue;
queue = help;
help = temp;
return res;
}

public boolean isEmpty() {
return queue.isEmpty();
}
}

3、测试

public static void main(String[] args) {
Main myStack = new Main();
Stack<Integer> stack = new Stack<>();

myStack.push(1);
myStack.push(2);
myStack.push(3);

stack.push(1);
stack.push(2);
stack.push(3);

System.out.println(myStack.peek());
System.out.println(stack.peek());
System.out.println("------------");

System.out.println(myStack.pop());
System.out.println(stack.pop());
System.out.println("------------");

System.out.println(myStack.pop());
System.out.println(stack.pop());
System.out.println("------------");

System.out.println(myStack.peek());
System.out.println(stack.peek());
}

【大厂算法笔试题 | 11】用栈实现队列、用队列实现栈系列问题_java_02


举报

相关推荐

0 条评论