Given an unsorted array, find the kth largest number in it.
Using the idea of divide and conquer, take a random number p from the array each time, put all the numbers greater than p on the left of p, and put the rest on the right of p, and mark the final subscript of p in the array as i, Then p is the i+1th largest number of the array.
If i+1 == k, the k-th largest number is p, and the algorithm ends.
If i+1 < k, the kth largest number is on the right side of p, and continue to find the k - i - 1th largest number in the array to the right of p.
If i + 1 > k, the kth largest number is on the left of p, and continue to find the kth largest number in the left array of p.
In the first version, I opened an extra array to store the numbers larger than p and smaller than p. This code is concise and easy to understand, but it will exceed the space limit.
class Solution(object): def findKthLargest(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int """ pivot = nums[0] small = [i for i in nums[1:] if i <= pivot] large = [i for i in nums[1:] if i > pivot] if len(large) + 1 == k: return pivot elif len(large) + 1 < k: return self.findKthLargest(small, k - len(large) - 1) else: return self.findKthLargest(large, k)Instead of using the extra space, just modify the original array.
class Solution(object): def findKthLargest(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int """ return self.findK(nums, 0, k, len(nums)) def findK(self, nums, start, k, end): pivot = nums[start] last_big = start # index of the last number greater than p for i in range(start + 1, end): if nums[i] > pivot: last_big += 1 nums[last_big], nums[i] = nums[i], nums[last_big] nums[last_big], nums[start] = nums[start], nums[last_big] # last_big变为p的下标 if last_big + 1 == k: return pivot elif last_big + 1 > k: return self.findK(nums, start, k, last_big) else: return self.findK(nums, last_big + 1, k, end) # Note that k does not need to be changed