https://leetcode.com/problems/kth-largest-element-in-an-array/#/description
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.
For example,
Given [3,2,1,5,6,4]
and k = 2, return 5.
Note:
You may assume k is always valid, 1 ? k ? array's length.
Sol:
Good problem to test your sorting skills out!
class Solution(object): def findKthLargest(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int """ # O(n) time, quicksort-Partition method # pos is an arbitrary postition in nums # the nums is seperated into two parts using "partition" method below. The front part has all elements smaller than nums[pos] while the end part has all elements bigger than nums[pos] #if len(nums) == 1: # return nums[0] #if len(nums) == 2: # if k == 1: # return max(nums[0], nums[1]) # if k == 2: # return min(nums[0], nums[0]) pos = self.partition(nums, 0, len(nums) - 1) # elements in the front part are smaller than nums[pos] if k < len(nums) - pos: return self.findKthLargest(nums[:pos], k - (len(nums) - pos)) # elements in the end part are bigger than nums[pos] elif k > len(nums) - pos: return self.findKthLargest(nums[pos+1:], k) else: return nums[pos] def partition(self, nums, l, r): pivot = nums[r] low = l for i in range(l, r): if nums[i] < pivot: nums[i], nums[low] == nums[low], nums[i] low += 1 nums[low], nums[r] = nums[r], nums[low] return low
Note:
For some reason, line "
pivot = nums[r]
" has the list index out of range error...
Other noteable answers:
# O(nlgn) time def findKthLargest1(self, nums, k): return sorted(nums, reverse=True)[k-1] # O(nk) time, bubble sort idea, TLE def findKthLargest2(self, nums, k): for i in xrange(k): for j in xrange(len(nums)-i-1): if nums[j] > nums[j+1]: # exchange elements, time consuming nums[j], nums[j+1] = nums[j+1], nums[j] return nums[len(nums)-k] # O(nk) time, selection sort idea def findKthLargest3(self, nums, k): for i in xrange(len(nums), len(nums)-k, -1): tmp = 0 for j in xrange(i): if nums[j] > nums[tmp]: tmp = j nums[tmp], nums[i-1] = nums[i-1], nums[tmp] return nums[len(nums)-k] # O(k+(n-k)lgk) time, min-heap def findKthLargest4(self, nums, k): heap = [] for num in nums: heapq.heappush(heap, num) for _ in xrange(len(nums)-k): heapq.heappop(heap) return heapq.heappop(heap) # O(k+(n-k)lgk) time, min-heap def findKthLargest5(self, nums, k): return heapq.nlargest(k, nums)[k-1] # O(n) time, quick selection def findKthLargest(self, nums, k): # convert the kth largest to smallest return self.findKthSmallest(nums, len(nums)+1-k) def findKthSmallest(self, nums, k): if nums: pos = self.partition(nums, 0, len(nums)-1) if k > pos+1: return self.findKthSmallest(nums[pos+1:], k-pos-1) elif k < pos+1: return self.findKthSmallest(nums[:pos], k) else: return nums[pos] # choose the right-most element as pivot def partition(self, nums, l, r): low = l while l < r: if nums[l] < nums[r]: nums[l], nums[low] = nums[low], nums[l] low += 1 l += 1 nums[low], nums[r] = nums[r], nums[low] return low
# k+(n-k)*log(k) time def findKthLargest1(self, nums, k): heap = nums[:k] heapq.heapify(heap) # create a min-heap whose size is k for num in nums[k:]: if num > heap[0]: heapq.heapreplace(heap, num) # or use: # heapq.heappushpop(heap, num) return heap[0] # O(n) time, quicksort-Partition method def findKthLargest(self, nums, k): pos = self.partition(nums, 0, len(nums)-1) if pos > len(nums) - k: return self.findKthLargest(nums[:pos], k-(len(nums)-pos)) elif pos < len(nums) - k: return self.findKthLargest(nums[pos+1:], k) else: return nums[pos] # Lomuto partition scheme def partition(self, nums, l, r): pivot = nums[r] lo = l for i in xrange(l, r): if nums[i] < pivot: nums[i], nums[lo] = nums[lo], nums[i] lo += 1 nums[lo], nums[r] = nums[r], nums[lo] return lo