题目地址:
https://www.lintcode.com/problem/kth-largest-element/description
给定一个数组,求其第 k k k大元素。
可以用经典的Quick Select算法。类似于快排,先将某个数选为pivot,然后将其放在“正确”的位置上(正确的位置指如果数组有序,其所该在的位置),然后根据这个位置是在第 k k k大元素左边还是右边,继续在一半边寻找。代码如下:
public class Solution {
/**
* @param n: An integer
* @param nums: An array
* @return: the Kth largest element
*/
public int kthLargestElement(int n, int[] nums) {
// write your code here
int l = 0, r = nums.length - 1;
// 数组的第n大元素等价于数组的第nums.length - n + 1小的元素,
// 其“正确”的下标应该是nums.length - n
int k = 0;
while ((k = partition(nums, l, r)) != nums.length - n) {
if (k < nums.length - n) {
l = k + 1;
} else {
r = k - 1;
}
}
return nums[k];
}
private int partition(int[] arr, int l, int r) {
int m = l + (r - l >> 1);
swap(arr, l, m);
int i = l, j = r;
int pivot = arr[i];
while (i < j) {
while (arr[j] >= pivot && j > i) {
j--;
}
arr[i] = arr[j];
while (arr[i] <= pivot && j > i) {
i++;
}
arr[j] = arr[i];
}
arr[i] = pivot;
return i;
}
private void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
平均时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)。