简体   繁体   中英

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

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 . If curr is greater, you can skip the second recursion because we won't need any of those values. 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. The heapq.nsmallest function uses a binary max-heap to solve this problem very elegantly. I strongly suggest checking it out !

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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