首先看这个表(C++用法):
区别 | queue | deque |
|---|---|---|
| 开闭 | 单端队列 | 双端队列 |
| 操作 | 只有队首 | 两头都行 |
| 访问 | 两头都行 | 两头都行 |
| 同样的操作 | q.empty();q.front();q.back();q.size() | |
| 不同的操作 | q.pop_front();q.pop_back();q.push_front();q.push_back() |
平常在写leetcode经常用LinkedList向上转型Deque作为栈或者队列使用
ArrayDeque和LinkedList都可以作为栈以及队列使用,但是从执行效率来说,ArrayDeque作为队列,以及LinkedList作为栈使用,会是更好的选择。
接下来看java用法:
Queue Deque
添加元素到队尾
E getFirst() / E peekFirst()
添加元素到队首 无 取队尾元素并删除 无 E removeLast() / E pollLast() 取队尾元素但不删除 无 E getLast() / E peekLast()
| 用法 | Queue | Deque |
|---|---|---|
| 添加元素到队尾 | add(E e) / offer(E e) | addLast(E e) / offerLast(E e) |
| 取队首元素并删除 | E remove() / E poll() | E removeFirst() / E pollFirst() |
| 取队首元素但不删除 | E element() / E peek() | E getFirst() / E peekFirst() |
deque的队尾也是同样的用法,First改成Last,而queue没有类似的用法
leetcode150 逆波兰表达式
class Solution {
public int evalRPN(String[] tokens) {
//首先第一步卡在数字字符判断上,如何把它们区分
Deque<Integer> stack = new LinkedList();
for (String s : tokens) {
if ("+".equals(s)) { // leetcode 内置jdk的问题,不能使用==判断字符串是否相等
stack.push(stack.pop() + stack.pop()); // 注意 - 和/ 需要特殊处理
} else if ("-".equals(s)) {
stack.push(-stack.pop() + stack.pop());
} else if ("*".equals(s)) {
stack.push(stack.pop() * stack.pop());
} else if ("/".equals(s)) {
int temp1 = stack.pop();
int temp2 = stack.pop();
stack.push(temp2 / temp1);
} else {
stack.push(Integer.valueOf(s));
}
}
return stack.pop();
}
}
这里主要是运用了queue,linkedlist作为栈去使用
leetcode239 滑动窗口最大值
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
ArrayDeque<Integer> deque = new ArrayDeque<>();
int[] res = new int[nums.length-k+1];
int idx = 0;
for(int i =0;i<nums.length;i++){
while(!deque.isEmpty() && deque.peek()<i-k+1){ //一开始把这里的i当做nums.length是不应该的,因为这里比较的是适合的索引位置
deque.poll();
}
while(!deque.isEmpty() && nums[deque.peekLast()]<nums[i]) {
deque.pollLast();
}
deque.offer(i);
if(i>=k-1) {
res[idx++] = nums[deque.peek()];
}
}
return res;
}
}
这道题则是运用了ArrayDeque,因为双端队列当队列处理起来更方便,并且能实现里面的值都为单调递增的。