150. 逆波兰表达式求值
思路:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。
代码如下:
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> stack =new Stack<>();
for(String s : tokens){
if(s.equals("+")){
stack.push(stack.pop()+stack.pop());
}else if(s.equals("-")){
stack.push(-stack.pop()+stack.pop());
}else if(s.equals("*")){
stack.push(stack.pop()*stack.pop());
}else if(s.equals("/")){
int temp1=stack.pop();
int temp2=stack.pop();
stack.push(temp2/temp1);
}else{
stack.push(Integer.parseInt(s));
}
}
return stack.pop();
}
}
注意:leetcode 内置jdk的问题,不能使用==判断字符串是否相等
239. 滑动窗口最大值
思路:考察队列的应用。维护一个单调非递增队列Deque,存放元素的下标。如果元素的下标小于滑动窗口的范围就poll掉,添加元素时要判断尾端的元素是否小于新加入的元素,true就将小元素remove直到单调队列中的元素大于新加入的元素。
代码如下:
class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
Deque<Integer> deque =new ArrayDeque<Integer>();
int[] res=new int[nums.length-k+1];
int index=0;
for(int i=0;i<nums.length;i++){
if(!deque.isEmpty() && deque.peek()<i-k+1){
deque.poll();
}
while(!deque.isEmpty() && nums[deque.peekLast()]<nums[i]){
deque.removeLast();
}
deque.offer(i);
if(i>=k-1){
res[index++]=nums[deque.peek()];
}
}
return res;
}
}
注意:当前k个元素都加进去后开始记录结果。
347.前 K 个高频元素
思路:该题的第一反应就是使用HashMap各个元素出现的次数,但具体如何排序和找到前k个元素就不知道如何去做了。这里比较好的一个解题方法是使用大顶堆和小顶堆来实现。
下面对进行介绍:
Java 中的大顶堆(Max Heap)和小顶堆(Min Heap)是基于二叉堆(Binary Heap)的数据结构。二叉堆是一种特殊的完全二叉树,其中每个父节点的关键字要么大于等于其子节点的关键字(大顶堆),要么小于等于其子节点的关键字(小顶堆)。
- 大顶堆(Max Heap):在大顶堆中,对于任意节点 i(除了叶子节点),满足以下条件:
heap[i] >= heap[2i+1] (左子节点)
heap[i] >= heap[2i+2] (右子节点) - 小顶堆(Min Heap):在小顶堆中,对于任意节点 i(除了叶子节点),满足以下条件:
heap[i] <= heap[2i+1] (左子节点)
heap[i] <= heap[2i+2] (右子节点)
在java中,大顶堆和小顶堆可以通过继承 PriorityQueue 类或自定义类来实现。PriorityQueue 默认是一个小顶堆,可以通过自定义比较器来实现大顶堆。
PriorityQueue介绍
PriorityQueue 是 Java 集合框架中的一个类,它实现了 Queue 接口,并提供了基于优先级队列的数据结构。优先级队列中每个元素都有一个优先级,通常具有较高优先级的元素会比具有较低优先级的元素更早被处理。
常用方法
- offer(E e):将元素添加到队列中,如果成功添加则返回 true。
- poll():检索并移除队列头部的元素,如果队列为空则返回 null。
- peek():检索但不移除队列头部的元素,如果队列为空则返回 null。
- isEmpty():如果队列为空则返回 true。
- size():返回队列中的元素数量。
- clear():移除队列中的所有元素。
构造函数
- PriorityQueue():创建一个初始容量为 11 的空优先队列。
- PriorityQueue(int initialCapacity):创建一个具有指定初始容量的空优先队列。
- PriorityQueue(int initialCapacity, Comparator<? super E> comparator):创建一个带有指定比较器的优先队列。
- PriorityQueue(Collection<? extends E> c):创建一个包含指定集合中的元素的优先队列。
- PriorityQueue(PriorityQueue q):创建一个包含指定优先队列中元素的新优先队列。
示例代码
- 使用自然排序
import java.util.PriorityQueue;
public class PriorityQueueExample {
public static void main(String[] args) {
// 创建一个 PriorityQueue,元素为 Integer 类型
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(5);
pq.offer(1);
pq.offer(3);
pq.offer(4);
pq.offer(2);
// 检索并移除队列头部的元素
while (!pq.isEmpty()) {
System.out.println(pq.poll()); // 输出 1, 2, 3, 4, 5
}
}
}
- 使用自定义比较器
import java.util.Comparator;
import java.util.PriorityQueue;
public class PriorityQueueExample {
public static void main(String[] args) {
// 创建一个 PriorityQueue,使用自定义比较器实现最大堆
PriorityQueue<Integer> pq = new PriorityQueue<>(Comparator.reverseOrder());
pq.offer(5);
pq.offer(1);
pq.offer(3);
pq.offer(4);
pq.offer(2);
// 检索并移除队列头部的元素
while (!pq.isEmpty()) {
System.out.println(pq.poll()); // 输出 5, 4, 3, 2, 1
}
}
}
- 使用整数数组的例子
如果你需要使用整数数组作为优先队列的元素,并根据数组的某个元素进行排序,可以使用下面的代码示例:
import java.util.Comparator;
import java.util.PriorityQueue;
public class PriorityQueueIntArrayExample {
public static void main(String[] args) {
// 创建一个 PriorityQueue,元素为 int[] 类型,根据数组中的第二个元素进行排序
PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]);
pq.offer(new int[]{1, 10});
pq.offer(new int[]{2, 5});
pq.offer(new int[]{3, 15});
pq.offer(new int[]{4, 1});
// 检索并移除队列头部的元素
while (!pq.isEmpty()) {
int[] arr = pq.poll();
System.out.println("[" + arr[0] + ", " + arr[1] + "]");
}
}
}
了解了以上内容,就可以使用小顶堆来解决本题了。
代码如下:
class Solution {
public int[] topKFrequent(int[] nums, int k) {
HashMap<Integer,Integer> map =new HashMap<>();
PriorityQueue<int[]> pq=new PriorityQueue<>((o1,o2) -> o1[1]-o2[1]);
int[] res= new int[k];
for(int num:nums){
map.put(num,map.getOrDefault(num,0)+1);
}
for(var x : map.entrySet()){
int[] temp=new int[2];
temp[0]=x.getKey();
temp[1]=x.getValue();
pq.offer(temp);
if(pq.size()>k){
pq.poll();
}
}
for(int i=0;i<k;i++){
res[i]=pq.poll()[0];
}
return res;
}
}