• 【力扣hot100】刷题笔记Day22


    前言

    • 局势紧迫起来了呀,同学们都开始找实习了,赶紧刷完hot100开找了

    215. 数组中的第K个最大元素 - 力扣(LeetCode)

    • 最小堆:O(nlogk)

        1. class Solution:
        2. def findKthLargest(self, nums: List[int], k: int) -> int:
        3. minheap = [] # 优先队列(最小堆),push和pop为O(logk)
        4. for num in nums:
        5. heapq.heappush(minheap, num) # 放入k个数,此时堆顶为最小值
        6. if len(minheap) > k: # 超过k个数就pop掉最小值
        7. heapq.heappop(minheap) # 剩下的就是前k大数
        8. return minheap[0] # 堆顶就是第k大数
    •  快速排序:O(n)

        1. # 快排模板
        2. def quick_sort(arr):
        3. if len(arr) <= 1: # 递归结束
        4. return arr
        5. else:
        6. pivot = arr[0] # 选择基准值
        7. less = [x for x in arr[1:] if x <= pivot] # 小的放左边
        8. greater = [x for x in arr[1:] if x > pivot] # 大的放右边
        9. return quick_sort(less) + [pivot] + quick_sort(greater) # 重新组合
        10. class Solution:
        11. def findKthLargest(self, nums: List[int], k: int) -> int:
        12. def quick_sort(nums, k):
        13. pivot = random.choice(nums) # 随机选择基准数防止退化成O(n2)
        14. big, equal, small = [], [], [] # 大于、等于、小于 pivot 的元素
        15. for num in nums:
        16. if num > pivot:
        17. big.append(num)
        18. elif num < pivot:
        19. small.append(num)
        20. else:
        21. equal.append(num)
        22. # 第k大元素在big里
        23. if k <= len(big):
        24. return quick_sort(big, k) # 递归进big里找
        25. # 第k大元素在small里
        26. elif k > len(nums) - len(small):
        27. return quick_sort(small, k - len(nums) + len(small)) # 递归进small里找
        28. # 第k大元素在equal里,直接返回pivot
        29. return pivot
        30. return quick_sort(nums, k)

     347. 前 K 个高频元素 - 力扣(LeetCode)

    • 参考郁郁雨学姐的题解
    • 计数器:O(nlogn)

        1. # 补充Counter用法,用于统计可哈希对象(比如列表、元组等)中每个元素的出现次数
        2. import collections
        3. nums = [1, 2, 3, 1, 2, 1]
        4. count = collections.Counter(nums)
        5. # 访问元素的计数
        6. print(count[1]) # 输出元素 1 出现的次数
        7. # 返回出现频率最高的元素及其出现次数
        8. most_common_elements = count.most_common(2) # 频率最高的前两个元素及其次数
        9. print(most_common_elements)
        10. # 更新 Counter 对象
        11. count.update([1, 2, 3]) # 更新计数器以包括新元素
        12. # 删除元素或重置元素计数
        13. del count[1] # 删除元素 1 的计数
        14. count.clear() # 清空计数器
        15. class Solution:
        16. def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        17. count = collections.Counter(nums)
        18. return [item[0] for item in count.most_common(k)]
    •  最小堆:O(nlogk)

        1. class Solution:
        2. def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        3. mp = {} # 统计频率
        4. for num in nums:
        5. mp[num] = mp.get(num, 0) + 1
        6. minheap = []
        7. for num, freq in mp.items():
        8. heapq.heappush(minheap, (freq, num)) # 按照频率排序
        9. if len(minheap) > k: # 大于k就弹出最小值
        10. heapq.heappop(minheap) # 最后剩下频率前k
        11. return [item[1] for item in minheap] # 返回频率前k的num
    • 快速排序:O(n)

      • 快速排序算法还是不太熟,找了个讲Python排序的视频学学
        1. class Solution:
        2. def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        3. mp = {} # 统计频率
        4. for num in nums:
        5. mp[num] = mp.get(num, 0) + 1
        6. # mp = collections.Counter(nums)
        7. num_cnt = list(mp.items())
        8. topKs = self.findTopK(num_cnt, k, 0, len(num_cnt)-1)
        9. return [item[0] for item in topKs]
        10. def findTopK(self, num, k, l, r):
        11. if l >= r: return num[:k] # 递归到0/1个元素,说明已完成前k排序
        12. pivot = random.randint(l ,r) # 随机选择基准值下标
        13. num[pivot], num[l] = num[l], num[pivot] # 把基准数换到最左边
        14. pivot = l # 更新基准值下标
        15. swap_i = pivot + 1 # 用于交换较小值
        16. for i in range(l + 1, r + 1):
        17. if num[i][1] > num[pivot][1]: # 把大于基准数的放左边(和快排相反)
        18. num[i], num[swap_i] = num[swap_i], num[i]
        19. swap_i += 1
        20. num[swap_i-1], num[pivot] = num[pivot], num[swap_i-1] # 把基准值放中间
        21. pivot = swap_i - 1 # 此时基准值在中间
        22. if k == pivot: # 左边正好是前k大数
        23. return num[:k]
        24. elif k > pivot: # 左边不足前k大数,去右边找
        25. return self.findTopK(num, k, pivot + 1, r)
        26. else: # 左边超过前k大数,去左边找
        27. return self.findTopK(num, k, l, pivot - 1)

     295. 数据流的中位数 - 力扣(LeetCode)

    • 最小堆 + 最大堆

      • 参考K神题解
        1. from heapq import *
        2. class MedianFinder:
        3. def __init__(self):
        4. self.A = [] # 小顶堆,保存较大的一半
        5. self.B = [] # 大顶堆,保存较小的一半
        6. def addNum(self, num: int) -> None:
        7. if len(self.A) != len(self.B): # m > n,奇数,补充B
        8. heappush(self.A, num)
        9. heappush(self.B, -heappop(self.A)) # 淘汰下的最小值放到B里
        10. else: # m = n,偶数,补充A
        11. heappush(self.B, -num)
        12. heappush(self.A, -heappop(self.B)) # 淘汰下的最大值放到A里
        13. def findMedian(self) -> float:
        14. if len(self.A) != len(self.B): # m > n,奇数
        15. return self.A[0]
        16. else: # m = n,偶数
        17. return (self.A[0] - self.B[0]) / 2.0

    后言

    • 学快排学了好久,脑子要炸掉了,另外想注册Claude发现接不了码注册不了了,可恶,浪费我学习时间,呸!
  • 相关阅读:
    [算法前沿]--015-中文大模型ChatGLM微调:P-Tuning,LoRA,Full parameter<上>
    通讯网关软件005——利用CommGate X2OPC实现OPC客户端访问MS SQL服务器
    1095:数1的个数(信奥)
    C# 访问 null 字段会抛异常原因探究
    手把手教你用C语言制作七夕流星雨---优雅永不过时(详细教程)
    [网络工程师]-应用层协议-Telnet
    【JVM技术专题】深入分析CG管理和原理查缺补漏「番外篇」
    分布式任务调度平台XXL-JOB安装及使用
    配电室远程运维平台:现代化的电力管理解决方案
    从Bitcask存储模型谈超轻量级KV系统设计与实现
  • 原文地址:https://blog.csdn.net/qq_56077562/article/details/136472201