ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【排序】力扣347:前K个高频元素(未完)

2022-04-04 21:03:03  阅读:196  来源: 互联网

标签:Counter 数组 nums 复杂度 元素 力扣 347 频率 排序


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

示例:

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

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

3种方法:部分快排思想;直接排序;优先队列

方法1:最小堆

  1. 借助【哈希表】来建立数字和其出现次数的映射,遍历一遍数组统计元素的频率
  2. 维护一个元素数目为 k 的最小堆
  3. 每次都将新的元素与堆顶元素(堆中频率最小的元素)进行比较
  4. 如果新的元素的频率比堆顶端的元素大,则弹出堆顶端的元素,将新的元素添加进堆中
  5. 最终,堆中的 k 个元素即为前 k 个高频元素

作者:cxywushixiong
链接:https://leetcode-cn.com/problems/top-k-frequent-elements/solution/leetcode-di-347-hao-wen-ti-qian-k-ge-gao-pin-yuan-/

时间复杂度:O(nlogk),n 表示数组的长度。首先,遍历一遍数组统计元素的频率,这一系列操作的时间复杂度是O(n);接着,遍历用于存储元素频率的 map,如果元素的频率大于最小堆中顶部的元素,则将顶部的元素删除并将该元素加入堆中,这里维护堆的数目是 k,所以这一系列操作的时间复杂度是 O(nlogk) 的;因此,总的时间复杂度是 O(nlog⁡k)。
空间复杂度:O(n),最坏情况下(每个元素都不同),map 需要存储 n 个键值对,优先队列需要存储 k 个元素,因此,空间复杂度是 O(n)。

方法2:桶排序
设置若干个桶,每个桶存储出现频率相同的数。桶的下标表示数出现的频率,即第 i 个桶中存储的数出现的频率为 i。
把数都放到桶之后,从后向前遍历桶,最先得到的 k 个数就是出现频率最多的的 k 个数。

首先依旧使用哈希表统计频率,统计完成后,创建一个数组,将频率作为数组下标,对于出现频率不同的数字集合,存入对应的数组下标即可。


时间复杂度:O(n),n 表示数组的长度。首先,遍历一遍数组统计元素的频率,这一系列操作的时间复杂度是 O(n);桶的数量为 n+1,所以桶排序的时间复杂度为 O(n);因此,总的时间复杂度是 O(n)。
空间复杂度:很明显为 O(n)。

方法3:python的Counter()
统计每个数的频率,输出最大的几个,这完全迎合了Python中的Counter类,调用其的几个方法即可。

Counter 是一个在collections包里的类,正如其名,是一个用于计数的工具。
我们可以用Counter(nums)这样的构造函数构造一个Counter类,其中nums是一个列表。
构造好的Counter实例可以看作一个字典,键是nums的每一项,值是它的出现次数。
如果上面的叙述让你感到很混乱的话,我不妨举个例子。
如果一个列表a = [1,1,3,4,3],你想要统计每项的出现次数,那么你使用b = Counter(a),那么这时候b就像一个这样的字典{1:2,3:2,4:1},表示数字1出现了2次,数字3出现了2次,数字4出现了1次。
可是题目里要我们输出的是最多的K项,这时候可以应用Counter的一个函数,most_common(k),这个函数就是返回最多出现的K项
但是返回的形式是一个元祖列表,类似[(1,2),(3,2),(4,1)]的形式,我们只需要键也就是第一项,所以要使用列表生成式处理一下即可。

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        from collections import Counter
        return [i[0] for i in Counter(nums).most_common(k)]

作者:qsctech-sange
链接:https://leetcode-cn.com/problems/top-k-frequent-elements/solution/yi-xing-python3dai-ni-zou-jin-counterlei-by-jimmy0/

标签:Counter,数组,nums,复杂度,元素,力扣,347,频率,排序
来源: https://www.cnblogs.com/Jojo-L/p/16100394.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有