LCR 060. 前 K 个高频元素

题目要求

leetcode地址

给定一个整数数组 nums 和一个整数 k ,请返回其中出现频率前 k 高的元素。可以按 任意顺序 返回答案。

示例

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:

输入: nums = [1], k = 1
输出: [1]

提示

  • 1 <= nums.length <= 105
  • k 的取值范围是 [1, 数组中不相同的元素的个数]
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

进阶

所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。

思路

哈希表+小顶堆

  1. 首先,将数组中的数字及出现次数存入hash表,有Map<num,num出现的次数>;
  2. 以num出现的次数为比较对象,维护一个小顶堆heap,遍历map将其中的元素以数组的形式[num,num出现的次数]不断添加到小顶堆,
    当heap.size()>K时,弹出最顶端元素(只返回前K大元素,而小顶堆顶端元素最小);
  3. 从heap中取出元素num添加到数组返回。

java中堆的实现

1
2
3
4
5
6
7
8
9
//小根堆,默认容量11
PriorityQueue<Integer> minHeap = new PriorityQueue<Integer>();
//大根堆,容量11
PriorityQueue<Integer> maxHeap = new PriorityQueue<Integer>(11,new Comparator<Integer>(){
@Override
public int compare(Integer i1,Integer i2){
return i2-i1;
}
});

代码实现(java)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public int[] topKFrequent(int[] nums, int k) {
// 哈希表存储
HashMap<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
map.put(num, map.getOrDefault(num, 0) + 1);
}
// 创建小顶堆
PriorityQueue<int[]> heap = new PriorityQueue<int[]>(new Comparator<int[]>() {
public int compare(int[] m, int[] n) {
return m[1] - n[1];
}
});

for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
heap.add(new int[] { entry.getKey(), entry.getValue() });
if (heap.size() > k) {
heap.poll();
}
}
int[] res = new int[k];
for (int i = 0; i < k; i++) {
res[i] = heap.poll()[0];
}
return res;
}
}

代码实现(golang)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
func topKFrequent(nums []int, k int) []int {
occurrences := map[int]int{}
for _, num := range nums {
occurrences[num]++
}
h := &IHeap{}
heap.Init(h)
for key, value := range occurrences {
heap.Push(h, [2]int{key, value})
if h.Len() > k {
heap.Pop(h)
}
}
ret := make([]int, k)
for i := 0; i < k; i++ {
ret[k - i - 1] = heap.Pop(h).([2]int)[0]
}
return ret
}

type IHeap [][2]int

func (h IHeap) Len() int { return len(h) }
func (h IHeap) Less(i, j int) bool { return h[i][1] < h[j][1] }
func (h IHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }

func (h *IHeap) Push(x interface{}) {
*h = append(*h, x.([2]int))
}

func (h *IHeap) Pop() interface{} {
old := *h
n := len(old)
x := old[n-1]
*h = old[0 : n-1]
return x
}

LCR 060. 前 K 个高频元素
https://liuxx1106.github.io/2024/01/12/algorithm-offer060/
作者
巨鹿
发布于
2024年1月12日
许可协议