给定一个大小为n
的数组,问题是要按排序顺序返回前k
个最小的元素。
我的想法是更新QuickSort算法,首先找到第一个k
元素,然后递归更新问题以找到k-1
个最大元素。
找不到我的错误在哪里。
def partition(a, left, right):
pivot = a[left]
p = left
q = right
while(p < q):
while(a[q] > pivot and p < q):
q-=1
while(a[p] <= pivot and p < q):
p+=1
a[p] , a[q] = a[q] , a[p]
a[left],a[p]=a[p],a[left]
return p
def kthSmallest(a, left, right, k,c=0):
if left>=right:
return a[c:]
else:
curr = partition(a, left, right)
if curr - left == k - 1:
return kthSmallest(a, left,curr-left-1,k-1,c+1)
if(curr - left > k - 1):
return kthSmallest(a, left, curr-1, k,c)
return kthSmallest(a, curr+1, right, k - (curr - left + 1),c)
temp=[8,5,2,1,6,7,4,9,0]
print(kthSmallest(a,0,len(temp)-1,2))
答案 0 :(得分:1)
您的递归对我来说真的没有任何意义。大多数情况下,您应该遵循快速排序的常规算法,可以避免对数组中不需要的部分进行排序(保证值超过第k个)。
这就是我要做的。您始终在左侧分区上进行递归,如果枢轴索引curr
小于k
,则始终在右侧分区上递归。如果curr
较大,则可以跳过第二次递归,因为我们不需要任何这些值。我将切片分割为一个非递归函数,因此我们不需要在每个递归调用中都这样做。
def partial_sort(a, left, right, k):
if left >= right: # base case, do nothing
return
curr = partition(a, left, right)
partial_sort(a, left, curr-1) # always recurse on the left partition
if curr < k: # we only sometimes need to recurse twice
partial_sort(a, curr+1, right)
def kthSmallest(a, k):
partial_sort(a, 0, len(a)-1, k)
return a[:k]
我还想指出,有一种稍微有效的算法来解决这种精确的计算,并且它在Python标准库中有一个实现。 heapq.nsmallest
函数使用二进制最大堆来非常优雅地解决此问题。我强烈建议checking it out!
答案 1 :(得分:-1)
如果我对您的问题正确,则可以使用:
min_k_values = np.sort(x, axis = None)[:k]