解题思路:这道题可以有多种实现方法,下面介绍主要的三种(1)堆排序(2)快排(3)全排序,然后取前k个最小值
(1)堆排序:先用数组前k个数构建一个大顶堆,然后依次遍历后size-k个数,如果当前元素小于堆顶,则删除堆顶,在堆中插入当前元素,这个可以同时完成,代码如下:
class Solution:
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
size = len(arr)
if k == 0:
return []
if size == k:
return arr
def shiftdown(start, end): #[start, end)
pivot = arr[start]
child = start * 2 + 1
while(child < end):
if child + 1 < end and arr[child] < arr[child+1]:
child = child + 1
if arr[child] <= pivot:
break
else:
arr[start] = arr[child]
start, child = child, 2 * child + 1
arr[start] = pivot
for i in range(k // 2 - 1, -1, -1): #前k个元素构造大顶堆
shiftdown(i, k)
for i in range(k, size):
if arr[i] < arr[0]:
arr[0], arr[i] = arr[i], arr[0]
shiftdown(0, k)
return arr[:k]
(2)快排:每次随机选取一个pivot,将小于等于pivot的放在pivot的左边,将大于pivot的放在pivot的右边,最终pivot的位置就是正确排序后pivot的index,将index 和k以及k-1进行比较:(1)小于k-1,继续对[k:size]进行快排,(2)如果index>k,[0:index]进行排序(3)直接返回前k个元素,代码如下:
import random
class Solution:
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
size = len(arr)
if k == 0:
return []
if size == k:
return arr
def quicksort(left, right):
p= random.randint(left, right)
pivot = arr[p]
arr[p] = arr[left]
l, r = left, right
while(left < right):
while(left < right and pivot < arr[right]):
right -= 1
arr[left] = arr[right]
while(left < right and arr[left] <= pivot):
left += 1
arr[right] = arr[left]
arr[left] = pivot
if left < k -1:
quicksort(left+1, r)
elif left > k:
quicksort(l, left-1)
quicksort(0, size-1)
return arr[:k]
(3)可以用python自带的排序函数进行排序,然后返回前k个值
class Solution:
def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
return sorted(arr)[:k]