题目描述:

image-20250115005140959

解析:一开始想的是先做排序,把小于k的放在一个新数组,然后执行合并操作,判断是否大于k,大于拿出新数组,小于的话在排序,再重复操作。如果数组最后剩一个数且小于k,count+1即可。但是时间复杂度太高。想用堆,但是java的堆不熟,抄了官解。

​ 首先来学习Java PriorityQueue(优先队列)

PriorityQueue类是一种队列数据结构实现,其中根据优先级处理对象。它与遵循FIFO(先进先出)算法的标准队列不同。优先级队列的头是队列中最小的元素。

​ Java集合框架中提供了PriorityQueuePriorityBlockingQueue两种类型的优先级队列,PriorityQueue是线程不安全的,PriorityBlockingQueue是线程安全的,这里主要使用PriorityQueue。

​ 在优先级队列中,添加的对象根据其优先级。默认情况下,优先级由对象的自然顺序决定。队列构建时提供的比较器可以覆盖默认优先级。

boolean add(object):将指定的元素插入此优先级队列。如果队列已满,则会引发异常。
boolean offer(object):将指定的元素插入此优先级队列。如果队列已满,则返回false
boolean remove(object):从此队列中删除指定元素的单个实例(如果存在)。
Object poll():检索并删除此队列的头部,如果此队列为空,则返回null
Object element():检索但不删除此队列的头部,如果此队列为空,则返回null
Object peek():检索但不删除此队列的头部,如果此队列为空,则返回null
void clear():从此优先级队列中删除所有元素。
Comparator comparator():返回用于对此队列中的元素进行排序的比较器,如果此队列根据其元素的自然顺序排序,则返回null
boolean contains(Object o):如果此队列包含指定的元素,则返回true
Iterator iterator():返回此队列中元素的迭代器。
int size():返回此队列中的元素数。
Object [] toArray():返回包含此队列中所有元素的数组。

代码:

package January;

import java.util.PriorityQueue;

/**
* @author hxw
* @version 1.0
* @date 2025/1/15 0:34
* @description: 3066. 超过阈值的最少操作数 II 中等
*/
public class fifteen {
public static void main(String[] args) {
int result = fifteen.Solution.minOperations(new int[]{2, 11, 10, 1, 3}, 10);
System.out.println(result);
}

class Solution {
public static int minOperations(int[] nums, int k) {
int res = 0;
PriorityQueue<Long> pq = new PriorityQueue<>();
for (long num : nums) {
pq.offer(num);//把数组中的数放到优先队列中
}
while (pq.peek() < k) {
long x = pq.poll(), y = pq.poll();//取两个最小的数并删除
pq.offer(x + x + y);//执行合并操作并插入
res++;
}
return res;
}
}
}