February——215.数组中的第k个最大元素&最小堆

128 篇文章 0 订阅
4 篇文章 0 订阅

 

class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        #直接排序,然后找到第k个最大的元素
        nums_res = sorted(nums,reverse=True)
        return nums_res[k-1]


        #构建一个大小为k的最小堆,堆顶元素就是第k个最大的元素
        heap = nums
        heapq.heapify(heap)

        while len(heap)>k:
            heapq.heappop(heap)
        
        return heap[0]

 

 

 

class Solution:
    def thirdMax(self, nums: List[int]) -> int:
        if len(set(nums))<3:
            return max(nums)
        
        #最小堆:插入时间复杂度是log(n)
        heap = list(set(nums))
        heapq.heapify(heap)
 
        while len(heap)>3:
            heapq.heappop(heap)
        
        return heap[0]

        #排序
        nums = list(set(nums))
        nums_res = sorted(nums,reverse=True)
        return nums_res[2]

        #O(n)时间复杂度
        nums = set(nums)
        n = len(nums)
        if n < 3:
            return max(nums)
        max1 = max(nums)
        nums.remove(max1)
        max2 = max(nums)
        nums.remove(max2)

        return max(nums)

前两个都不满足O(n)时间复杂度,只有最后一个满足O(n)时间复杂度。

 

class Solution:
    def topKFrequent(self, words: List[str], k: int) -> List[str]:
        
        #堆操作
        #时间复杂度:O(Nlogk)
        num_dic = dict(Counter(words))
        import heapq  
        h = []
        res = []
        for key, value in num_dic.items():
            heapq.heappush(h, (-value, key))  # 按第一个键值进行排序,堆顶是最小值,如果第一个元素相同那就按照第二个元素进行排序
        
        for _ in range(k):
            res.append(heapq.heappop(h)[1])
        
        return res
        



        
        #时间复杂度:O(NlogN)
        count = collections.Counter(words)
        candidates = count.keys()
        #先按照value进行排序,如果value排序相同,在按照key进行排序
        candidates = sorted(candidates,key = lambda x:(-count[x],x))
        return candidates[:k]
        

这个题目麻烦就麻烦在要求出现频次相同的时候需要按照字母的顺序进行排序,因此我们还是采用两个方法;①字典+排序;②最小堆。

  • 字典+排序
    • 用hash表统计每个单词出现的次数
    • 取出key,然后进行升序排序,排序的一句是value取负数,如果value相同那就按照单词进行排序
    • 最终返回前k个元素即可,因为我们给value加了负号,加完负之前的最大值就变成最小值,因此返回前k个元素即可
  • 最小堆
    • 构建一个最小堆,根据-value,如果value相同,那我们就按照第二个元素进行排序
    • 然后弹出栈顶的k的元素,这k个元素就是出现频率最高的三个元素

 

 

class Solution:
    def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]:
        

        #直接排序法
        points.sort(key=lambda x: (x[0] ** 2 + x[1] ** 2))
        return points[:K]



        #建一个最小堆,然后不断的堆顶的元素。
        distance = []
        for i in range(len(points)):
            x,y = points[i][0],points[i][1]
            distance.append(x*x+y*y)
        dic = defaultdict(int)
        #字典的key是index,value是点到原点之间的距离
        for i in range(len(distance)):
            dic[i]= distance[i]
        heap = []
        res = []
        for key,value in dic.items():
            heapq.heappush(heap,(value,key))
           
        for _ in range(K):
            index = heapq.heappop(heap)[1]
            res.append(points[index])

       

        return res
  • 直接排序法
    • 计算出距离,直接排序,然后挑选前k个元素即可
  • 构建最小堆法
    • 先计算出来距离
    • 然后构建字典,key是index,value是距离
    • 然后构建最小堆,从最小堆堆顶取出k个元素即可
    • 取出的k个元素只是index,然后根据index在列表中取出坐标即可

 总结:最小堆的一个简单应用。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值