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.
解题思路:
这题是比较古老的排序题目了,经典的表述是求数组中第k大或者第k小的数字。这种题,用一个O(nlogn)的比较排序,然后直接取第k个 第(前)k大数问题 的总结。
我以前也转载过相关解法 求已知N个数中第k小的数。
这道题的解法是比较综合的。首先,递归分治,借鉴了快速排序的思路,将数组根据任意元素(这里取第一个)分成两半,a.如果从end到pivot正好k个,那么就是第pivot个元素。b.如果end到pivot>k个,递归处理pivot+1到end,取第k个。c.如果小于k个,则取前半段(start到pivot-1),取第k-(end - pivot+1)个。
其次,根据上面的表述,和binary search也很像吧。一不小心就会出现stack overflow的问题,开始我就写错了,注释掉了。因为在pivot==start的时候,start得不到更新,死循环了。
时间复杂度,因为上面的b和c每次只选择执行一次,而不是像快排,每次两个都要执行。所以时间复杂度为O(n)。
因为O(n+n/2+n/4...) = O(2n)。
public class Solution { public int findKthLargest(int[] nums, int k) { return find(nums, 0, nums.length - 1, k); } public int find(int[] nums, int start, int end, int k) { if(start > end) { return -1; } int pivot = partition(nums, start, end); if(end - pivot + 1 == k) { return nums[pivot]; } else if(end - pivot + 1 > k) { // return find(nums, pivot, end, k); return find(nums, pivot + 1, end, k); } else { return find(nums, start, pivot - 1, k - (end - pivot + 1)); } } public int partition(int[] nums, int start, int end) { if(start == end) { return start; } int pivot = start + 1; for(int i = start + 1; i <= end; i++) { if(nums[i] < nums[start]) { int temp = nums[pivot]; nums[pivot] = nums[i]; nums[i] = temp; pivot++; } } int temp = nums[pivot - 1]; nums[pivot - 1] = nums[start]; nums[start] = temp; return pivot - 1; } }