剑指40刷题记录:最小k个数

# @Author : Aulicz
# @File : sword_toward40getLeastNumbers.py
# @Software: PyCharm
# @Version:0.01


# 输入整数数组 arr ,找出其中最小的 k 个数。例如,输入 4、5、1、6、2、7、3、8 这 8 个数字,则最小的 4 个数字是 1、2、3、4 。
# 1.以最暴力的排序完成此题,时复O(nlogn),空复O(logn)
# 但是题需要找最小的k个不要求顺序,实际上只需要排序中间过程的某个结果
# 2.堆,先拿k个数建堆,然后查后面的数是否可以入堆,时复O(nlogk),空复O(k)
import heapq
from typing import List


class Solution:
    # 暴力解法,草,两行写完了
    def getLeastNumbers1(self, arr: List[int], k: int) -> List[int]:
        arr.sort()
        return arr[:k]

    # 堆的解法
    def getLeastNumbers2(self, arr: List[int], k: int) -> List[int]:
        if k == 0:
            return []
        # python默认只能最小堆
        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])
        res = [-x for x in hp]
        return res

    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
        if k == 0:
            return []
        l = arr
        b = 0
        e = len(l) - 1
        return self.quickSort(l, b, e, k-1)

    def quickSort(self, l: list, begin: int, end: int, index: int):
        mid = self.partition(l, begin, end)
        if mid == index:
            return l[:index + 1]
        elif mid > index:
            return self.quickSort(l, begin, mid - 1, index)
        else:
            return self.quickSort(l, mid + 1, end, index)
        return l

    # 分成左右两端,返回mid
    def partition(self, l: list, begin: int, end: int):
        # 如果将快排写在一个函数里是需要这段的
        # if begin+1 >= end:
        #     return
        piv = l[begin]
        # 这里不复制left,end也可以,因为不需要递归
        i = begin
        j = end  # 标准快排此处需要-1
        while i < j:
            while i < j and piv <= l[j]:
                j -= 1
            l[i] = l[j]
            while i < j and piv >= l[i]:
                i += 1
            l[j] = l[i]
        l[i] = piv
        return i

    # 以下是大佬的写法
    def partition1(self, l: list, begin: int, end: int):
        piv = l[end]
        i = begin - 1
        # 这个快排写法绝了
        for j in range(begin, end):
            if l[j] <= piv:
                i += 1
                l[i], l[j] = l[j], l[i]
        l[i + 1], l[end] = l[end], l[i + 1]
        return i + 1

l1 = [9, 7, 2, 3, 4, 5, 10, 8, 1, 6]
solution = Solution()
b = 0
e = len(l1) - 1
k = 4
print(solution.quickSort(l1, b, e, k-1))

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值