Skip to main content

347. 前 K 个高频元素 [medium]

347. 前 K 个高频元素 [medium]

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

给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例 1:

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

示例 2:

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

提示:

  • 你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。
  • 你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。
  • 你可以按任意顺序返回答案。

通过次数109,208提交次数177,125

Second Try

2020-10-06

看了题解,需要考虑n个元素都是独立的情况,因此first try中的复杂度可能出现O(nlgn)的情况,还是需要上优先队列。

使用最小堆保留数字,说是最小堆,其实保存的反而是最大的k个数字,因此每次超出数量的时候使用heappop弹出的都是最小值,剩下的k个都大于最小值。

最小堆复杂度为O(nlgk), 每次pop和push一个元素的复杂度都是O(lgk), 总共n个元素都需要过一遍。

看题解还可以使用快排,什么时候小于pivot的数值凑够了k就可以终止,并且每次pivot index都使用随机数,这样勉强也小于O(nlgn).

class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
counter = collections.Counter(nums)

heap = []
for key, value in counter.items():
heapq.heappush(heap, [value, key])
if len(heap) > k: # k 差点与 for k, v in counter.items()混淆
heapq.heappop(heap)
return [v for k, v in heap]
  • 执行用时:56 ms, 在所有 Python3 提交中击败了52.25%的用户
  • 内存消耗:16 MB, 在所有 Python3 提交中击败了93.86%的用户

First Try

2020-10-06

第一波统计数量是O(N), 第二波是O(KlgK), K是不同元素的数量,整体复杂度勉强小于O(nlgn).

不过如果只是这个级别,感觉也只是easy难度,而不是medium?

class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
c = collections.Counter(nums)
rv = sorted(c.items(), key = lambda x: x[1], reverse=True)[:k]
return [k for k, v in rv]

  • 执行用时:56 ms, 在所有 Python3 提交中击败了52.25%的用户
  • 内存消耗:16.1 MB, 在所有 Python3 提交中击败了75.17%的用户