简体   繁体   English

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

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

Given an array of size n , the problem is to return first k smallest elements, in sorted order. 给定大小为n的数组,问题是按排序顺序返回前k最小元素。 My idea was to update an QuickSort algorithm , to find first the first k element and then recursive update problem to find k-1 biggest elements. 我的想法是更新QuickSort算法,首先找到第一个k元素然后再递归更新问题以找到k-1最大元素。 Can't find where my mistake is. 找不到我的错误。

    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))

Your recursion doesn't really make sense to me. 你的递归对我来说并没有多大意义。 You should mostly want to follow the normal algorithm for quicksort, you can just avoid sorting the parts of the array you don't care about (the values that are guaranteed to be past the k'th). 你应该主要想要遵循quicksort的常规算法,你可以避免排序你不关心的数组部分(保证超过k的值)。

Here's how I'd do it. 这是我怎么做的。 You always recurse on the left partition, and recurse on the right partition if the pivot index curr is less than k . 您总是在左侧分区上递归,如果枢轴索引curr小于k ,则递归到右侧分区。 If curr is greater, you can skip the second recursion because we won't need any of those values. 如果curr更大,您可以跳过第二次递归,因为我们不需要任何这些值。 I'm splitting the slice out into a non-recursive function, so we don't need to be doing it on every recursive call. 我正在将切片拆分为非递归函数,因此我们不需要在每次递归调用时都这样做。

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]

I'd also like to note that there's a slightly more efficient algorithm to solve this exact calculation, and it has an implementation in the Python standard library. 我还要注意,有一种稍微更有效的算法来解决这个精确的计算,并且它在Python标准库中有一个实现。 The heapq.nsmallest function uses a binary max-heap to solve this problem very elegantly. heapq.nsmallest函数使用二进制最大堆来非常优雅地解决这个问题。 I strongly suggest checking it out ! 我强烈建议您查看它

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

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

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

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