堆(Heap)是一种特殊的树形数据结构,通常是一个完全二叉树。在堆中,每个节点都满足堆的性质:
堆通常使用数组来实现存储。对于完全二叉树,假设根节点存储在数组索引为 0 的位置,对于任意节点存储在数组索引为 i 的位置:
2 * i + 1
的位置。2 * i + 2
的位置。(i - 1) // 2
的位置(向下取整)。O(nlogn)
时间复杂度内对数组进行排序。Link: https://leetcode.cn/problems/g5c51o/description/
def heapAppend(heap, nMap, num):
heap.append(num)
cur = len(heap) - 1
parent = (cur - 1) // 2
while parent >= 0:
if nMap[heap[cur]] < nMap[heap[parent]]:
heap[cur], heap[parent] = heap[parent], heap[cur]
cur = parent
parent = (cur - 1) // 2
def heapify(heap, nMap, i):
if i >= len(heap):
return
leftChild = 2 * i + 1
rightChild = 2 * i + 2
minEle = i
if leftChild < len(heap) and nMap[heap[leftChild]] < nMap[heap[minEle]]:
minEle = leftChild
if rightChild < len(heap) and nMap[heap[rightChild]] < nMap[heap[minEle]]:
minEle = rightChild
if minEle != i:
heap[minEle], heap[i] = heap[i], heap[minEle]
heapify(heap, nMap, minEle)
def stack(heap, nMap, k):
for num in nMap.keys():
if len(heap) < k:
heapAppend(heap, nMap, num)
else:
if nMap[num] < nMap[heap[0]]:
continue
else:
heap[0] = num
heapify(heap, nMap, 0)
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
nMap = {}
heap = []
for num in nums:
if num not in nMap:
nMap[num] = 1
else:
nMap[num] += 1
stack(heap, nMap, k)
return heap
用Python的heapq实现:
import heapq
def stack(heap, nMap, k):
for num in nMap.keys():
if len(heap) < k:
heapq.heappush(heap, (nMap[num], num))
else:
if nMap[num] < heap[0][0]:
continue
else:
heapq.heapreplace(heap, (nMap[num], num))
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
nMap = {}
heap = []
for num in nums:
if num not in nMap:
nMap[num] = 1
else:
nMap[num] += 1
stack(heap, nMap, k)
return [x[1] for x in heap]