LeetCode经典数据结构设计题目
剑指 Offer 09. 用两个栈实现队列
代码思路
- 栈,先进后出,意味着局部进来的顺序与弹出顺序是逆序
- 需要将顺序转换为正序,通过另一个栈作为中转,那么逆序的逆序输出时就是正序
- 那么bStack就是队列的输出顺序
- 当bStack不为空时,直接输出
- 当bStack为空时,将aStack的所有数据都弹出,压入bStack,逆序完成
- 队列,先进先出,意味着进来的顺序与弹出顺序一致
155. 最小栈class CQueue {
Stack<Integer> aStack;
Stack<Integer> bStack;
public CQueue() {
this.aStack = new Stack<>();
this.bStack = new Stack<>();
}
public void appendTail(int value) {
aStack.add(value);
}
public int deleteHead() {
if(!bStack.isEmpty()) return bStack.pop();
if(aStack.isEmpty()) return -1;
while(!aStack.isEmpty()) bStack.add(aStack.pop());
return bStack.pop();
}
}
155. 最小栈
代码思路:
- 保留一个最小值min,且获取min的时间复杂度是O(1),那么可以考虑添加一个辅助栈,记录栈中当前最小值,辅助栈不严格递减即可
- 当添加一个元素val,维护辅助栈
- 若栈为空或者val不大于栈顶元素,将当前元素压入
- 当移除一个元素top,判断是否移除了最小值min
- 若移除了最小值min,minStack弹出min
class MinStack {
Stack<Integer> common;
Stack<Integer> minStack;
public MinStack() {
common = new Stack<>();
minStack = new Stack<>();
}
public void push(int x) {
if(minStack.isEmpty() || minStack.peek()>=x) minStack.add(x);
common.add(x);
}
public void pop() {
if(common.isEmpty()) return;
int top = common.pop();
if(top==minStack.peek())
{
minStack.pop();
}
}
public int top() {
if(common.isEmpty()) return -1;
return common.peek();
}
public int min() {
if(minStack.isEmpty()) return -1;
return minStack.peek();
}
}
面试题59 - II. 队列的最大值
代码思路: 单调队列,简单说就是新来的比早来的还 ‘强’,那么‘旧人’走(单调队列像资本家,就是很残酷)
单调队列分为单调递增和单调递减队列,其实就是压入元素时,处理方法不同,以单调递增队列maxQ为例
当add新增一个元素value
当maxQ为空,压入队列
从队尾开始,将比value小的移除队列,value才能入队(所以单调队列采用双端队列实现)
当正常队列移除元素时,判断是否移除了最大值(maxQ的队头元素)
- 若移除最大值,maxQ队头出队即可
class MaxQueue {
LinkedList<Integer> queue;
LinkedList<Integer> maxQ;
public MaxQueue() {
this.queue = new LinkedList<>();
this.maxQ = new LinkedList<>();
}
public int max_value() {
if(maxQ.isEmpty()) return -1;
return maxQ.peekFirst();
}
public void push_back(int value) {
while(!maxQ.isEmpty() && value>maxQ.peekLast()) maxQ.removeLast();
maxQ.addLast(value);
queue.</