今天做到了合并元素,使用了优先队列,有点小题大做,但是还是想总结一下,优先队列处理topN问题的好处。
前k个高频元素
给你一个整数数组 nums
和一个整数 k
,请你返回其中出现频率前 k
高的元素。你可以按 任意顺序 返回答案。
使用优先队列快速A掉,总共花费四分钟,虽然用时看起来吓人
public static int[] topKFrequent(int[] nums, int k) {
//优先队列解决topn问题
Map<Integer, Integer> map = new HashMap<>();
PriorityQueue<Integer> queue = new PriorityQueue<>((x, y) ->
map.get(y) - map.get(x));
for (int i = 0; i < nums.length; i++) {
map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);
}
//进行统计完毕后,进行排序操作
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
queue.offer(entry.getKey());
}
int[] result = new int[k];
for (int i = 0; i < k; i++) {
result[i] = queue.poll();
}
return result;
}
数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
这道题也可以直接使用优先队列 根堆进行处理
public int findKthLargest(int[] nums, int k) {
//声明优先队列
PriorityQueue<Integer> queue = new PriorityQueue<>((x1, x2) -> x2 - x1);
//可以进行只放前两个数据
for (int i = 0; i < nums.length; i++) {
queue.offer(nums[i]);
}
for (int i = 0; i < k-1; i++) {
queue.poll();
}
return queue.poll();
}
虽然能快速A掉算法 但是还需要了解一下底层内部排序的操作。
这类问题也可使用快排进行排序,然后去最大值等等都是可行的
如果时间来得及的话感觉还是需要了解一下底层代码,看下官方堆排序的实现
class Solution {
public int findKthLargest(int[] nums, int k) {
int heapSize = nums.length;
buildMaxHeap(nums, heapSize);
for (int i = nums.length - 1; i >= nums.length - k + 1; --i) {
swap(nums, 0, i);
--heapSize;
maxHeapify(nums, 0, heapSize);
}
return nums[0];
}
public void buildMaxHeap(int[] a, int heapSize) {
for (int i = heapSize / 2; i >= 0; --i) {
maxHeapify(a, i, heapSize);
}
}
public void maxHeapify(int[] a, int i, int heapSize) {
int l = i * 2 + 1, r = i * 2 + 2, largest = i;
if (l < heapSize && a[l] > a[largest]) {
largest = l;
}
if (r < heapSize && a[r] > a[largest]) {
largest = r;
}
if (largest != i) {
swap(a, i, largest);
maxHeapify(a, largest, heapSize);
}
}
public void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}