- class Solution:
- def findKthLargest(self, nums: List[int], k: int) -> int:
- minheap = [] # 优先队列(最小堆),push和pop为O(logk)
- for num in nums:
- heapq.heappush(minheap, num) # 放入k个数,此时堆顶为最小值
- if len(minheap) > k: # 超过k个数就pop掉最小值
- heapq.heappop(minheap) # 剩下的就是前k大数
- return minheap[0] # 堆顶就是第k大数
- # 快排模板
- def quick_sort(arr):
- if len(arr) <= 1: # 递归结束
- return arr
- else:
- pivot = arr[0] # 选择基准值
- less = [x for x in arr[1:] if x <= pivot] # 小的放左边
- greater = [x for x in arr[1:] if x > pivot] # 大的放右边
- return quick_sort(less) + [pivot] + quick_sort(greater) # 重新组合
-
-
- class Solution:
- def findKthLargest(self, nums: List[int], k: int) -> int:
- def quick_sort(nums, k):
- pivot = random.choice(nums) # 随机选择基准数防止退化成O(n2)
- big, equal, small = [], [], [] # 大于、等于、小于 pivot 的元素
- for num in nums:
- if num > pivot:
- big.append(num)
- elif num < pivot:
- small.append(num)
- else:
- equal.append(num)
- # 第k大元素在big里
- if k <= len(big):
- return quick_sort(big, k) # 递归进big里找
- # 第k大元素在small里
- elif k > len(nums) - len(small):
- return quick_sort(small, k - len(nums) + len(small)) # 递归进small里找
- # 第k大元素在equal里,直接返回pivot
- return pivot
-
- return quick_sort(nums, k)
- # 补充Counter用法,用于统计可哈希对象(比如列表、元组等)中每个元素的出现次数
- import collections
- nums = [1, 2, 3, 1, 2, 1]
- count = collections.Counter(nums)
- # 访问元素的计数
- print(count[1]) # 输出元素 1 出现的次数
- # 返回出现频率最高的元素及其出现次数
- most_common_elements = count.most_common(2) # 频率最高的前两个元素及其次数
- print(most_common_elements)
- # 更新 Counter 对象
- count.update([1, 2, 3]) # 更新计数器以包括新元素
- # 删除元素或重置元素计数
- del count[1] # 删除元素 1 的计数
- count.clear() # 清空计数器
-
- class Solution:
- def topKFrequent(self, nums: List[int], k: int) -> List[int]:
- count = collections.Counter(nums)
- return [item[0] for item in count.most_common(k)]
- class Solution:
- def topKFrequent(self, nums: List[int], k: int) -> List[int]:
- mp = {} # 统计频率
- for num in nums:
- mp[num] = mp.get(num, 0) + 1
- minheap = []
- for num, freq in mp.items():
- heapq.heappush(minheap, (freq, num)) # 按照频率排序
- if len(minheap) > k: # 大于k就弹出最小值
- heapq.heappop(minheap) # 最后剩下频率前k
- return [item[1] for item in minheap] # 返回频率前k的num
- class Solution:
- def topKFrequent(self, nums: List[int], k: int) -> List[int]:
- mp = {} # 统计频率
- for num in nums:
- mp[num] = mp.get(num, 0) + 1
- # mp = collections.Counter(nums)
- num_cnt = list(mp.items())
- topKs = self.findTopK(num_cnt, k, 0, len(num_cnt)-1)
- return [item[0] for item in topKs]
-
- def findTopK(self, num, k, l, r):
- if l >= r: return num[:k] # 递归到0/1个元素,说明已完成前k排序
- pivot = random.randint(l ,r) # 随机选择基准值下标
- num[pivot], num[l] = num[l], num[pivot] # 把基准数换到最左边
- pivot = l # 更新基准值下标
- swap_i = pivot + 1 # 用于交换较小值
- for i in range(l + 1, r + 1):
- if num[i][1] > num[pivot][1]: # 把大于基准数的放左边(和快排相反)
- num[i], num[swap_i] = num[swap_i], num[i]
- swap_i += 1
- num[swap_i-1], num[pivot] = num[pivot], num[swap_i-1] # 把基准值放中间
- pivot = swap_i - 1 # 此时基准值在中间
- if k == pivot: # 左边正好是前k大数
- return num[:k]
- elif k > pivot: # 左边不足前k大数,去右边找
- return self.findTopK(num, k, pivot + 1, r)
- else: # 左边超过前k大数,去左边找
- return self.findTopK(num, k, l, pivot - 1)
- from heapq import *
- class MedianFinder:
- def __init__(self):
- self.A = [] # 小顶堆,保存较大的一半
- self.B = [] # 大顶堆,保存较小的一半
-
- def addNum(self, num: int) -> None:
- if len(self.A) != len(self.B): # m > n,奇数,补充B
- heappush(self.A, num)
- heappush(self.B, -heappop(self.A)) # 淘汰下的最小值放到B里
- else: # m = n,偶数,补充A
- heappush(self.B, -num)
- heappush(self.A, -heappop(self.B)) # 淘汰下的最大值放到A里
-
- def findMedian(self) -> float:
- if len(self.A) != len(self.B): # m > n,奇数
- return self.A[0]
- else: # m = n,偶数
- return (self.A[0] - self.B[0]) / 2.0