# @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))
剑指40刷题记录:最小k个数
于 2023-06-25 15:36:17 首次发布
文章介绍了两种在Python中找到整数数组中最小的k个数的方法:一种是暴力排序,时间复杂度为O(nlogn);另一种是使用堆,时间复杂度为O(nlogk)。此外,还提供了一个基于快速排序的解决方案。
摘要由CSDN通过智能技术生成