1.题目
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
2.代码
使用堆处理问题(堆排序):
****************************
堆即用数组表示的树状结构
****************************
1.使用库函数:
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
count_dic = collections.Counter(nums)
items = list(count_dic.items())
max_heap = []
for i in items:
heapq.heappush(max_heap,(-i[1],i[0]))
res = []
while k >0:
res.append(heapq.heappop(max_heap)[1])
k-=1
return res
2.使用小跟堆求topk大问题:
'''
维护一个长度为k 的堆。
topk小:构建一个 k 个数的大根堆,当读取的数小于根节点时,替换根节点,向下调整。
topk大:构建一个 k 个数的小跟堆,当读取的数大于根节点时,替换根节点,向下调整。
以 topk 大为例: 小跟堆 ==> 越往上越小,若小于跟则小于整个堆,对大小为k ⇒ 有k个比它大的数就不是k大。
'''
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
# 向下调整
def adjustDown(A,k,lens):
# A[0]用于暂存A[K],真正的heap是A[1:]
A[0] = A[k]
i = 2*k
while i<lens:
if i+1<lens and A[i][1]>A[i+1][1]:
i +=1
if A[0][1] <= A[i][1]: break
else:
A[k] = A[i]
k = i
i *=2
A[k] = A[0]
# 建堆
def buildMinHeap(A,lens):
i = lens//2
while i>0:
adjustDown(A,i,lens)
i -=1
# 交换函数
def swap(t1,t2):
return t2,t
count_dic = collections.Counter(nums)
items = list(count_dic.items())
# A[0]用来暂存A[K]的,真正的heap是A[1:],所以heap长度+1
heap = [(0,0)]
# 建大小为k+1的堆
for i in range(k):
heap.append(items[i])
buildMinHeap(heap,k+1)
# 若大于跟则替换向下调整
for i in range(k,len(items)):
if items[i][1]>heap[1][1]:
heap[1] = items[i]
adjustDown(heap,1,k+1)
# 舍A[0]
return [t[0] for t in heap[1:]]
3.使用大跟堆求topk大问题:
'''
即堆排序
'''
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
# 向下调整
def adjustDown(A,k,lens):
# A[0]用于暂存A[K],真正的heap是A[1:]
A[0] = A[k]
i = 2*k
while i<lens:
if i+1<lens and A[i][1]<A[i+1][1]:
i +=1
if A[0][1] >= A[i][1]: break
else:
A[k] = A[i]
k = i
i *=2
A[k] = A[0]
# 建堆
def buildMaxHeap(A,lens):
i = lens//2
while i>0:
adjustDown(A,i,lens)
i -=1
# 交换
def swap(t1,t2):
return t2,t1
# 堆排序,将前k大加入res
# 将最后一位与A[1]交换,并从A[1]开始向下调整
def heapSort(A,lens,res,k):
i = lens-1
while i>=1 and k>0:
# print(A)
res.append(A[1][0])
A[i],A[1] = swap(A[i],A[1])
adjustDown(A,1,i)
i -=1
k -=1
count_dic = collections.Counter(nums)
items = list(count_dic.items())
# A[0]用来暂存A[K]的,真正的heap是A[1:],所以heap长度+1
heap = [(0,0)]
# 建立大小为len(items)+1 的堆
lens = len(items)
for i in range(lens):
heap.append(items[i])
buildMinHeap(heap,lens+1)
res = []
heapSort(heap,lens+1,res,k)
return res