栈与队列
232.用栈实现队列
需要用到两个栈:stackIn,stackOut
stackIn:记录入栈
stackOut:记录出栈,如果栈为空,则把stackIn中元素全部入栈,形成出队队列。
225. 用队列实现栈
两个队列:que1,que2
que1:交换后的que1形成栈模式
que2:作为辅助。入队先进入que2;如果que1不为空,再把que1的元素入队que2。然后交换que1和que2。
20. 有效的括号
1047. 删除字符串中的所有相邻重复项
150. 逆波兰表达式求值
是比较常规的三道题,通过入栈出栈都能解决。代码实现在细节方面需要增强。
额外记录java字符串转整数类型的方法:
String str = "123";
//字符串转int类型
Integer num1 = new Integer(str);
int num2 = Integer.parseInt(str);
Integer num3 = Integer.valueOf(str);
//输出
num1=123
num2=123
num3=123
239. 滑动窗口最大值 (一刷至少需要理解思路)
一刷思路理通了,但是对于单调队列还不是很熟练。
347.前 K 个高频元素 (一刷至少需要理解思路)
1、利用map.getOrDefault() 方法 获得每个元素及其重复出现的次数 存储在map(num, count)中。
2、声明一个优先级队列,遍历map.entrySet()——entrySet 获取 k-v Set集合;并将set集合转为int[2]数组,放入队列中,按count从小到大排序。(小堆栈)
以下是如何将set集合转为int[2]数组:
for(Map.Entry<Integer,Integer> entry:map.entrySet()){
//大顶堆需要对所有元素进行排序
pq.add(new int[]{entry.getKey(),entry.getValue()});
}
3、当放入队列后,队列个数大于k时,输出队列元素(当前最小值)。
4、遍历结束,输出当前的堆栈中存放数组的num值。
总结
Java Deque
Deque是一个双端队列接口,继承自Queue接口,Deque的实现类是LinkedList、ArrayDeque、LinkedBlockingDeque,其中LinkedList是最常用的。
Deque当栈用时:
入栈 | push(E e) |
出栈 | poll() / pop() 后者在栈空的时候会抛出异常,前者返回null |
查看栈顶元素 | peek() 为空时返回null |
Deque当队列用时:
入队 | offer(E e) |
出队 | poll() 为空时返回null |
查看队首 | peek() 为空时返回null |
其他方法
第一个元素(头部) | 最后一个元素(尾部) | |||
抛出异常 | 特殊值 | 抛出异常 | 特殊值 | |
插入 | addFirst(e) | offerFirst(e) | addLast(e) | offerLast(e) |
删除 | removeFirst() | pollFirst() | removeLast() | pollLast() |
检查 | getFirst() | peekFirst() | getLast() | peekLast() |
Java PriorityQueue
Java集合框架中提供了PriorityQueue和PriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,这里主要使用PriorityQueue。
PriorityQueue 的底层是堆,堆的底层是数组。
自定义排序
PriorityQueue当中,最小的元素就是优先级最高的元素。默认升序排序
我们可以通过在构造方法中引入 Comparator 来实现自定义顺序,但是代码看起来十分臃肿,这是我们可以使用 lambda 表达式来简化。
引入 Comparator 的做法:将升序排序转为降序排序
PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
lambda 表达式的做法:
PriorityQueue<Integer> pq = new PriorityQueue<>(((o1, o2) -> {
return o2 - o1;
}));
//再进一步简化
PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o2 - o1);
优先级队列的构造:三种方式
static void PriorityQueueDemo() {
//1、创建一个空的优先级队列,默认底层容量是11
PriorityQueue<Integer> queue1 = new PriorityQueue<>();
//2、创建一个空的优先级队列,底层的容量是 initialCapacity
PriorityQueue<Integer> queue2 = new PriorityQueue<>(50);
//3、用 ArrayList 集合来创建一个优先级队列的对象
ArrayList<Integer> list = new ArrayList<>();
list.add(4);
list.add(0);
list.add(2);
list.add(3);
PriorityQueue<Integer> queue3 = new PriorityQueue<>(list);
System.out.println(queue3);
}
常用方法:
入队列 | add(e) | offer(e) |
出队列 | remove(e) | poll(e) |
队首元素 | element(e) | peek(e) |
获取个数 | size() | |
清空 | clean() | |
是否为空 | isEmpty() |