Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
一、题目描述
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
例1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
例2:
输入: nums = [1], k = 1
输出: [1]
进阶: 你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。
二、解题思路
先去看了一波标签,好家伙,数组、哈希表、分治、桶排序、计数、快速选择、排序、堆(优先队列)。其实这道题分两步,先遍历计一遍数然后再排序找出前k大,这里排序最快的方法是建个堆,而JS没有,所有打算用python,转念一想python有个非常适合这道题的数据结构Counter,于是写了个偷懒版的(但是使用堆也算是用轮子,只是封装的程度不同罢了)。
三、AC代码
from collections import Counter
class Solution(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
c = Counter()
for item in nums:
c[item] += 1
res = [i[0] for i in c.most_common(k)]
return res
四、总结
贴一个比较规整的使用最大堆的答案:
public int[] topKFrequent(int[] nums, int k) {
//先统计每个数字出现的次数
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums)
map.put(num, map.getOrDefault(num, 0) + 1);
//最大堆
PriorityQueue<int[]> priorityQueue = new PriorityQueue<>((a, b) -> b[1] - a[1]);
for (int key : map.keySet())
priorityQueue.add(new int[]{key, map.get(key)});
//取堆中最大的k个元素
int[] res = new int[k];
for (int i = 0; i < k; i++)
res[i] = priorityQueue.poll()[0];
return res;
}
作者:数据结构和算法
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-medium/xvzpxi/?discussion=qfyTUW