用数组实现栈
public class ArrayStack {
private Integer[] arr;
private Integer size;
public ArrayStack(int initSize) {
if (initSize < 0) {
throw new IllegalArgumentException("the init size is less than 0");
}
arr = new Integer[initSize];
size = 0;
}
public Integer peek() {
if (size == 0) {
return null;
}
return arr[size-1];
}
public void push(int obj) {
if (size == arr.length) {
throw new ArrayIndexOutOfBoundsException("the queue is full");
}
arr[size++] = obj;
}
public Integer pop() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("the queue is empty");
}
return arr[--size];
}
}
用数组实现队列
public class ArrayQueue {
private Integer[] arr;
private Integer start;
private Integer end;
private Integer size;
public ArrayQueue(Integer initSize) {
if (initSize < 0) {
throw new IllegalArgumentException("the init size is less than 0");
}
arr = new Integer[initSize];
start = 0;
end = 0;
size = 0;
}
public Integer peek() {
if (size == 0) {
return null;
}
return arr[start];
}
public void push (Integer obj) {
if (size == arr.length) {
throw new ArrayIndexOutOfBoundsException("the queue is full");
}
size++;
arr[end] = obj;
end = end == arr.length-1 ? 0 : end + 1;
}
public Integer poll() {
if (size == 0) {
throw new ArrayIndexOutOfBoundsException("the queue is empty");
}
size--;
Integer tmp = start;
start = start == arr.length - 1 ? 0 : start + 1;
return arr[tmp];
}
}
两个队列实现栈
public class TwoQueueStack {
private Queue<Integer> queueData;
private Queue<Integer> help;
public TwoQueueStack() {
queueData = new LinkedList<Integer>();
help = new LinkedList<Integer>();
}
public void push(int value) {
queueData.add(value);
}
public int peek() {
while (queueData.size() !=1 ) {
help.add(queueData.poll());
}
int res = queueData.poll();
help.add(res);
swap();
return res;
}
public int pop() {
while (queueData.size() > 1) {
help.add(queueData.poll());
}
int res = queueData.poll();
swap();
return res;
}
public void swap() {
Queue<Integer> temp = help;
help = queueData;
queueData = temp;
}
}
单调栈
单调队列
public int[] maxSlidingWindow(int[] nums, int k ){
if( nums.length == 0 && k == 0 ) return new int[0];
int[] res = new int[nums.length - k +1];
Deque<Integer> deque = new LinkedList<>();
for( int j = 0, i = 1 - k; j < nums.length; i++, j++){
if( i > 0 && deque.peekFirst() == nums[i-1]) {
deque.removeFirst();
}
while(!deque.isEmpty() && deque.peekLast() < nums[j]) {
deque.removeLast();
}
deque.addLast(nums[j]);
if( i >= 0 ){
res[i] = deque.peekFirst();
}
}
return res;
}
剑指09-用两个栈实现队列
public class _09_两个栈实现队列 {
private Stack<Integer> inStack;
private Stack<Integer> outStack;
public _09_两个栈实现队列() {
inStack = new Stack<>();
outStack = new Stack<>();
}
public void appendTail(int value) {
inStack.push(value);
}
public int deleteHead() {
if(outStack.isEmpty()){
while(!inStack.isEmpty()){
outStack.push(inStack.pop());
}
}
return outStack.isEmpty() ? -1 : (int)outStack.pop();
}
}
- 关键点解析:
- 两个栈:其中一个做输入栈,另外一个做输入栈
- push操作:只需要输入栈push就行
- pop操作:需要将输入栈的元素全部弄到输出栈中;如果这个时候输入栈中又出现新添加元素,需要等输出栈中的元素全部pop完,再弄到输出栈。
剑指30- 包含min函数的栈
public class _30_包含min函数的栈 {
private Stack<Integer> dataStack;
private Stack<Integer> minStack;
public _30_包含min函数的栈() {
minStack = new Stack<Integer>();
dataStack = new Stack<Integer>();
}
public void push(int x) {
dataStack.push(x);
if(minStack.isEmpty() || minStack.peek() >= x){
minS.push(x);
}
}
public void pop() {
if(dataStack.pop().equals(minStack.peek())){
minStack.pop();
}
}
public int top() {
return dataStack.peek();
}
public int min() {
return minStack.peek();
}
}
- 关键点解析
- 借用最小栈维护最小值在栈顶,同样最大值也同理
- 建立最小栈的时候,比较需要等号
- 数据栈pop的时候,最小栈栈顶数据如果相同,则需要pop输出
- equals的使用:Integer的缓存[-128,127],如果使用==,数字超过缓存范围则不相同
剑指59-1-滑动窗口的最大值
public class _59_滑动窗口的最大值 {
public int[] maxSlidingWindow(int[] nums, int k) {
if(nums == null || nums.length == 0) {
return new int[0];
}
int[] res = new int[nums.length - k + 1];
Deque<Integer> queue = new ArrayDeque<>();
for(int i = 0, j = 0; i < nums.length; i++) {
if(!queue.isEmpty() && i - queue.peek() >= k) {
queue.poll();
}
while(!queue.isEmpty() && nums[i] > nums[queue.peekLast()]) {
queue.pollLast();
}
queue.offer(i);
if(i >= k - 1) {
res[j++] = nums[queue.peek()];
}
}
return res;
}
}
剑指59-2- 队列的最大值
public class _59_队列的最大值 {
private Deque<Integer> queue;
private Deque<Integer> help;
public _59_队列的最大值() {
queue = new ArrayDeque<>();
help = new ArrayDeque<>();
}
public int max_value() {
return queue.isEmpty() ? -1 : help.peek();
}
public void push_back(int value) {
queue.offer(value);
while(!help.isEmpty() && value > help.peekLast()) {
help.pollLast();
}
help.offer(value);
}
public int pop_front() {
if(queue.isEmpty()) {
return -1;
}
int val = queue.pop();
if(help.peek() == val) {
help.pop();
}
return val;
}
}