Time: O(nlogn) if array is not almost sorted, Otherwise, O(n^2)
Space: O(1), inplace
method 2: heapsort
Time: O(Nlogk)
Space: O(k) for heap storage
4. Coding
QuickSelect (quicksort ) method
class Solution:
def findKth(self, a, n, K):
#
# method 1: quickselect
# method 2: heapsort
# input: a, n, k
#
#
if K >n or not a:
return None
return self.quickselect(a, 0, len(a)-1, K)
def quickselect(self, arr, start, end, k):
#
#1. partition arr into two part
# 2. get the pos of pivot
# 3. goto left or right array to find the k^th element
#
#binary search
while start <=end-1:
pivot = self.partition(arr, start,end)
if pivot <k-1:
start = pivot+1
elif pivot>k-1:
end = pivot -1
else:
return arr[pivot]
return arr[end]
def partition(self, arr, start, end):
if start >= end:
return end
pivot = end
stored_idx = start # store the first element that is greater than pivot
pt = start
while pt <end:
# since it is Kth largest, so sort it in descending order
if arr[pt] >= arr[pivot]:
arr[pt], arr[stored_idx] = arr[stored_idx], arr[pt]
stored_idx += 1
pt += 1
arr[stored_idx], arr[pivot] =arr[pivot], arr[stored_idx]
return stored_idx
2. Heap Sort method
class Solution:
def findKth(self, a, n, K):
# method2: heap sort
# 1. build a min-heap using first K element in array
# 2. use min-heap to pop the minimum element repeatedly until
# the heap contain only K leement. Then the last element as top k largest
#
#
# Time: O(klogk + (n-k)logk + logk) = O(nlogk)
# Build heap: O(klogk) for build heap, while loop O((n-k)logk), O(logk) for return result
#
import heapq
if K >n and not a:
return None
heap = [a[i] for i in range(K)]
heapq.heapify(heap)
pt = K
while pt < n:
heapq.heappush(heap, a[pt])
heapq.heappop(heap)
pt += 1
# return the minimum value in the K largest values of array
# that is TopK largest
return heapq.heappop(heap)