剑指offer40、最小的k个数(Python题解)

问题
在这里插入图片描述

题目来源:力扣(LeetCode)

剑指offer40.最小的k个数

难度:简单

分析
本题提供两个题解,一是python技巧,一是堆方法。
使用堆方法,这个数组很大,因此不能建堆后依次从堆顶取元素,而是应该在建堆的过程中不断保留前k小的元素。最大堆用来取前k小元素,只要小于最大值(堆顶元素)就把堆顶pop掉,填入新值,不断迭代。
python内置的是最小堆,因此入堆的时候取个反,可以想象一个数轴来比较元素的大小。

解决方法
1:python技巧

#python技巧
#超80%
class Solution:
    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
        arr.sort()
        return arr[:k]

复杂度:O(nlogn)

2:堆方法

#堆方法
#python维护的是最小堆。求最小的k个数时维护大小为k的最大堆,这样就可以得到小于等于堆顶的k个数
#求最大的k个数,维护大小为k的最小堆,这样就可以得到大于等于堆顶的k个数
#python内置的是最小堆,所以这里我们将数值取反,求最大的k个数
#超80%
class Solution:
    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
        if k == 0:
            return []

        hp = [-x for x in arr[:k]]
        heapq.heapify(hp)   #建堆,使列表具有堆的性质
        for i in range(k, len(arr)):
            if -hp[0] > arr[i]: #是我们想要得到的数,入堆
                heapq.heappop(hp)   #弹出堆顶
                heapq.heappush(hp,-arr[i])    #入堆
        ans = [-x for x in hp]
        return ans

复杂度:O(nlogn)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值