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;
}
}
}
本文介绍两种有效的方法来找出未排序数组中的第K大元素。一种是通过排序数组直接获取,时间复杂度为O(nlogn);另一种是使用快速选择算法的递归版本,该方法更高效。同时提供了详细的算法实现代码。
849

被折叠的 条评论
为什么被折叠?



