题目:https://leetcode-cn.com/problems/top-k-frequent-elements/
思路1:计数,对数量进行桶排序
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
amount = collections.defaultdict(int) # 统计每个数字的数量
max_amount = 0 # 最大数量
for num in nums:
amount[num] += 1
max_amount = max(max_amount, amount[num])
buckets = [[] for _ in range(max_amount + 1)]
for num, count in amount.items():
buckets[count].append(num) # 同一个数量的数字放在一个桶里
ans = []
for i in range(len(buckets)-1, 0, -1):
for num in buckets[i]:
ans.append(num)
if len(ans) == k:
return ans
时间复杂度:O(n)
空间复杂度:O(n)
思路2:计数,最小堆
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
amount = collections.defaultdict(int) # 统计每个数字的数量
for num in nums:
amount[num] += 1
def heapify(arr, i, arr_len): # 以数量为标准最小堆的堆化
left = 2 * i + 1
right = 2 * i + 2
smallest = i
if left < arr_len and amount[arr[left]] < amount[arr[smallest]]:
smallest = left
if right < arr_len and amount[arr[right]] < amount[arr[smallest]]:
smallest = right
if smallest != i:
arr[i], arr[smallest] = arr[smallest], arr[i]
heapify(arr, smallest, arr_len)
ans = []
for num, count in amount.items():
if len(ans) < k:
ans.append(num)
if len(ans) == k: # 建造最小堆,只会建一次
for i in range(len(ans)//2 - 1, -1, -1):
heapify(ans, i, len(ans))
elif count > amount[ans[0]]:
ans[0] = num
heapify(ans, 0, len(ans))
return ans
时间复杂度:O(nlog2n)
空间复杂度:O(n)