马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
comments: true
edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20060.%20%E5%87%BA%E7%8E%B0%E9%A2%91%E7%8E%87%E6%9C%80%E9%AB%98%E7%9A%84%20k%20%E4%B8%AA%E6%95%B0%E5%AD%97/README.md
剑指 Offer II 060. 出现频率最高的 k 个数字
标题描述
给定一个整数数组 nums 和一个整数 k ,请返回其中出现频率前 k 高的元素。可以按 恣意序次 返答复案。
示例 1:
- <strong>输入: </strong>nums = [1,1,1,2,2,3], k = 2
- <strong>输出: </strong>[1,2]
复制代码 示例 2:
- <strong>输入: </strong>nums = [1], k = 1
- <strong>输出: </strong>[1]
复制代码
提示:
- 1 <= nums.length <= 105
- k 的取值范围是 [1, 数组中不相同的元素的个数]
- 标题数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
进阶:所设盘算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。
注意:本题与主站 347 题相同:https://leetcode.cn/problems/top-k-frequent-elements/
解法
方法一:哈希表 + 优先队列(小根堆)
利用哈希表统计每个元素出现的次数,然后利用优先队列(小根堆)维护前 k k k 个出现次数最多的元素。
时间复杂度 O ( n log k ) O(n\log k) O(nlogk)。
Python3
- class Solution:
- def topKFrequent(self, nums: List[int], k: int) -> List[int]:
- cnt = Counter(nums)
- return [v[0] for v in cnt.most_common(k)]
复制代码 Java
- class Solution {
- public int[] topKFrequent(int[] nums, int k) {
- Map<Integer, Long> frequency = Arrays.stream(nums).boxed().collect(
- Collectors.groupingBy(Function.identity(), Collectors.counting()));
- Queue<Map.Entry<Integer, Long>> queue = new PriorityQueue<>(Map.Entry.comparingByValue());
- for (var entry : frequency.entrySet()) {
- queue.offer(entry);
- if (queue.size() > k) {
- queue.poll();
- }
- }
- return queue.stream().mapToInt(Map.Entry::getKey).toArray();
- }
- }
复制代码 C++
- using pii = pair<int, int>;
- class Solution {
- public:
- vector<int> topKFrequent(vector<int>& nums, int k) {
- unordered_map<int, int> cnt;
- for (int v : nums) ++cnt[v];
- priority_queue<pii, vector<pii>, greater<pii>> pq;
- for (auto& [num, freq] : cnt) {
- pq.push({freq, num});
- if (pq.size() > k) {
- pq.pop();
- }
- }
- vector<int> ans(k);
- for (int i = 0; i < k; ++i) {
- ans[i] = pq.top().second;
- pq.pop();
- }
- return ans;
- }
- };
复制代码 Go
- func topKFrequent(nums []int, k int) []int {
- cnt := map[int]int{}
- for _, v := range nums {
- cnt[v]++
- }
- h := hp{}
- for v, freq := range cnt {
- heap.Push(&h, pair{v, freq})
- if len(h) > k {
- heap.Pop(&h)
- }
- }
- ans := make([]int, k)
- for i := range ans {
- ans[i] = heap.Pop(&h).(pair).v
- }
- return ans
- }
- type pair struct{ v, cnt int }
- type hp []pair
- func (h hp) Len() int { return len(h) }
- func (h hp) Less(i, j int) bool { return h[i].cnt < h[j].cnt }
- func (h hp) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
- func (h *hp) Push(v any) { *h = append(*h, v.(pair)) }
- func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v }
复制代码 TypeScript
- function topKFrequent(nums: number[], k: number): number[] {
- let hashMap = new Map();
- for (let num of nums) {
- hashMap.set(num, (hashMap.get(num) || 0) + 1);
- }
- let list = [...hashMap];
- list.sort((a, b) => b[1] - a[1]);
- let ans = [];
- for (let i = 0; i < k; i++) {
- ans.push(list[i][0]);
- }
- return ans;
- }
复制代码 Rust
- use std::collections::HashMap;
- impl Solution {
- pub fn top_k_frequent(nums: Vec<i32>, k: i32) -> Vec<i32> {
- let mut map = HashMap::new();
- let mut max_count = 0;
- for &num in nums.iter() {
- let val = map.get(&num).unwrap_or(&0) + 1;
- map.insert(num, val);
- max_count = max_count.max(val);
- }
- let mut k = k as usize;
- let mut res = vec![0; k];
- while k > 0 {
- let mut next = 0;
- for key in map.keys() {
- let val = map[key];
- if val == max_count {
- res[k - 1] = *key;
- k -= 1;
- } else if val < max_count {
- next = next.max(val);
- }
- }
- max_count = next;
- }
- res
- }
- }
复制代码 Swift
- import HeapModule
- class Solution {
- func topKFrequent(_ nums: [Int], _ k: Int) -> [Int] {
- var frequency: [Int: Int] = [:]
- for num in nums {
- frequency[num, default: 0] += 1
- }
- var freqHeap = Heap<FreqElement>()
- for (key, value) in frequency {
- freqHeap.insert(.init(val: key, freq: value))
- if freqHeap.count > k {
- freqHeap.removeMin()
- }
- }
- var ans = [Int]()
- while let element = freqHeap.popMax() {
- ans.append(element.val)
- }
- return ans
- }
- }
- struct FreqElement: Comparable {
- let val: Int
- let freq: Int
- static func < (lhs: FreqElement, rhs: FreqElement) -> Bool {
- lhs.freq < rhs.freq
- }
- static func == (lhs: FreqElement, rhs: FreqElement) -> Bool {
- lhs.freq == rhs.freq
- }
- }
复制代码 方法二
Python3
- class Solution:
- def topKFrequent(self, nums: List[int], k: int) -> List[int]:
- cnt = Counter(nums)
- hp = []
- for num, freq in cnt.items():
- heappush(hp, (freq, num))
- if len(hp) > k:
- heappop(hp)
- return [v[1] for v in hp]
复制代码 Java
- class Solution {
- public int[] topKFrequent(int[] nums, int k) {
- Map<Integer, Integer> cnt = new HashMap<>();
- for (int v : nums) {
- cnt.put(v, cnt.getOrDefault(v, 0) + 1);
- }
- PriorityQueue<int[]> pq = new PriorityQueue<>((a, b) -> a[1] - b[1]);
- for (var e : cnt.entrySet()) {
- pq.offer(new int[] {e.getKey(), e.getValue()});
- if (pq.size() > k) {
- pq.poll();
- }
- }
- int[] ans = new int[k];
- for (int i = 0; i < k; ++i) {
- ans[i] = pq.poll()[0];
- }
- return ans;
- }
- }
复制代码 TypeScript
- function topKFrequent(nums: number[], k: number): number[] {
- const map = new Map<number, number>();
- let maxCount = 0;
- for (const num of nums) {
- map.set(num, (map.get(num) ?? 0) + 1);
- maxCount = Math.max(maxCount, map.get(num));
- }
- const res = [];
- while (k > 0) {
- for (const key of map.keys()) {
- if (map.get(key) === maxCount) {
- res.push(key);
- k--;
- }
- }
- maxCount--;
- }
- return res;
- }
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |