347. 前 K 个高频元素

leetcode链接:
https://leetcode.cn/problems/top-k-frequent-elements/

题目分析

方法一:简单粗暴,先循环查看每个数值出现的次数,安装此处将其放入到 优先队列 中,取出优先队列中的数值,即可得到需要的答案。

方案一

简单粗暴,先循环查看每个数值出现的次数,安装此处将其放入到 优先队列 中,取出优先队列中的数值,即可得到需要的答案。

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
class Solution {
public int[] topKFrequent(int[] nums, int k) {

int[] result = new int[k];

HashMap<Integer, Integer> hashMap = new HashMap<>();

for (int i = 0; i < nums.length; i++) {
if (hashMap.containsKey(nums[i])) {
hashMap.put(nums[i], hashMap.get(nums[i]) + 1);
} else {
hashMap.put(nums[i], 1);
}
}

PriorityQueue<Map.Entry<Integer, Integer>> priorityQueue = new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() {
@Override
public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
return o2.getValue().compareTo(o1.getValue());
}
});

for (Map.Entry e : hashMap.entrySet()) {
priorityQueue.add(e);
}

for (int i = 0; i < k; i++) {
result[i] = priorityQueue.poll().getKey();
}

return result;
}
}

结果

解答成功:
执行耗时:13 ms,击败了42.62% 的Java用户
内存消耗:46.6 MB,击败了7.25% 的Java用户

分析

时间复杂度:
O( )

空间复杂度:
O( )

官方题解

https://leetcode.cn/problems/top-k-frequent-elements/solution/qian-k-ge-gao-pin-yuan-su-by-leetcode-solution/

方法二:基于快速排序

对「出现次数数组」进行排序,以求得最大值。

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
38
39
40
41
42
43
44
45
46
47
48
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> occurrences = new HashMap<Integer, Integer>();
for (int num : nums) {
occurrences.put(num, occurrences.getOrDefault(num, 0) + 1);
}

List<int[]> values = new ArrayList<int[]>();
for (Map.Entry<Integer, Integer> entry : occurrences.entrySet()) {
int num = entry.getKey(), count = entry.getValue();
values.add(new int[]{num, count});
}
int[] ret = new int[k];
qsort(values, 0, values.size() - 1, ret, 0, k);
return ret;
}

public void qsort(List<int[]> values, int start, int end, int[] ret, int retIndex, int k) {
int picked = (int) (Math.random() * (end - start + 1)) + start;
Collections.swap(values, picked, start);

int pivot = values.get(start)[1];
int index = start;
for (int i = start + 1; i <= end; i++) {
if (values.get(i)[1] >= pivot) {
Collections.swap(values, index + 1, i);
index++;
}
}
Collections.swap(values, start, index);

if (k <= index - start) {
qsort(values, start, index - 1, ret, retIndex, k);
} else {
for (int i = start; i <= index; i++) {
ret[retIndex++] = values.get(i)[0];
}
if (k > index - start + 1) {
qsort(values, index + 1, end, ret, retIndex, k - (index - start + 1));
}
}
}
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/top-k-frequent-elements/solution/qian-k-ge-gao-pin-yuan-su-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

方法一:堆,与方案一类似

此方法和方案一类似,仅作参考

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
class Solution {
public int[] topKFrequent(int[] nums, int k) {
Map<Integer, Integer> occurrences = new HashMap<Integer, Integer>();
for (int num : nums) {
occurrences.put(num, occurrences.getOrDefault(num, 0) + 1);
}

// int[] 的第一个元素代表数组的值,第二个元素代表了该值出现的次数
PriorityQueue<int[]> queue = new PriorityQueue<int[]>(new Comparator<int[]>() {
public int compare(int[] m, int[] n) {
return m[1] - n[1];
}
});
for (Map.Entry<Integer, Integer> entry : occurrences.entrySet()) {
int num = entry.getKey(), count = entry.getValue();
if (queue.size() == k) {
if (queue.peek()[1] < count) {
queue.poll();
queue.offer(new int[]{num, count});
}
} else {
queue.offer(new int[]{num, count});
}
}
int[] ret = new int[k];
for (int i = 0; i < k; ++i) {
ret[i] = queue.poll()[0];
}
return ret;
}
}

作者:LeetCode-Solution
链接:https://leetcode.cn/problems/top-k-frequent-elements/solution/qian-k-ge-gao-pin-yuan-su-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


347. 前 K 个高频元素
http://yuanql.top/2023/07/10/02_leetcode/347. 前 K 个高频元素/
作者
Qingli Yuan
发布于
2023年7月10日
许可协议