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.
// method 1: O(nlogn) public int findKthLargest1(int[] nums, int k) { Arrays.sort(nums); return nums[nums.length - k]; } // method 2: quick select: standard recursive version public int findKthLargest2(int[] nums, int k) { quickSelect(nums, k, 0, nums.length - 1); return nums[nums.length - k]; } private static final int CUTOFF = 10; public void quickSelect(int[] nums, int k, int left, int right) { if (left + CUTOFF <= right) { int pivot = median3(nums, left, right); int i = left, j = right - 1; while (true) { while(nums[++i] < pivot) {} while(nums[--j] > pivot) {} if (i < j) { swap(nums, i, j); } else { break; } } swap(nums, i, right - 1); if (nums.length - k < i) quickSelect(nums, left, i - 1, k); else if (nums.length - k > i) quickSelect(nums, i + 1, right, k); } else { insertionSort(nums, left, right); } } private int median3(int[] nums, int left, int right) { int mid = (left + right) / 2; if (nums[mid] < nums[left]) swap(nums, left, mid); if (nums[mid] > nums[right]) swap(nums, mid, right); if (nums[mid] < nums[left]) swap(nums, left, mid); swap(nums, mid, right - 1); return nums[right - 1]; } private void swap(int[] nums, int p1, int p2) { int tmp = nums[p1]; nums[p1] = nums[p2]; nums[p2] = tmp; } private void insertionSort(int[] nums, int left, int right) { for (int i = left + 1; i <= right; i++) { if (nums[i] < nums[i - 1]) { int tmp = nums[i]; int j = i - 1; for (; j >= 0 && tmp < nums[j]; j--) { nums[j + 1] = nums[j]; } nums[j + 1] = tmp; } } }