繁体   English   中英

数组中的k-最小值按排序顺序排列

[英]k-smallest values in array in a sorted order

给定大小为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))

你的递归对我来说并没有多大意义。 你应该主要想要遵循quicksort的常规算法,你可以避免排序你不关心的数组部分(保证超过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函数使用二进制最大堆来非常优雅地解决这个问题。 我强烈建议您查看它

如果我的问题得到解决,你可以使用:

 min_k_values = np.sort(x, axis = None)[:k]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM