题目
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.
Example 1:
Input: [3,2,1,5,6,4]
and k = 2
Output: 5
Example 2:
Input: [3,2,3,1,2,4,5,5,6]
and k = 4
Output: 4
十分钟尝试
以前做过一个类似题目,是求最大的k个数,其实是一样的,这个题目是求第k大的数字。我当时那个题目也就是转化为这个题目解决的。写完了发现有个问题,我求的是第k大的数,是从小开始的,而题目的第k大,是从最大数字开始数的。比如
1 2 3 6 9,这个数组,第2大的数字是6,而我的算法是2. 稍微改动一下就可以。在分区的时候,大的放在右边,小的放在左边就可以了。代码如下:
class Solution {
public int findKthLargest(int[] nums, int k) {
k=nums.length-k+1;
shuffle(nums);
int res=quickSelect(nums,0,nums.length-1,k);
return res;
}
private void shuffle(int a[]) {
final Random random = new Random();
for(int index = 0; index < a.length; index++) {
final int r = random.nextInt(a.length-index)+index;
swap(a, index, r);
}
}
private int quickSelect(int[] nums,int low,int high,int k){
if (low > high) {
return 0;
}
int i = low, j = high;
while (i < j) {
while (i < j && nums[j] >= nums[low]) {
j --;
}
while (i < j && nums[i] <= nums[low]) {
i ++;
}
swap(nums, i, j);
}
swap(nums, low, i);
if(k == i - low + 1) {
return nums[i];
}
else if(k < i - low + 1) {
return quickSelect(nums, low, i - 1, k);
}
else {
return quickSelect(nums, i + 1, high, k - (i - low + 1));
}
}
private static void swap(int[] number, int i, int j) {
int t;
t = number[i];
number[i] = number[j];
number[j] = t;
}
}
代码利用了选择排序,基于快速排序的思想,基本代码一样,只是选择了在哪个区间进行排序。调试过程中出现了问题,逻辑怎么感觉没问题,结果就是不对,原来参数顺序写的不一致,一定要注意参数顺序一致:
quickSelect(nums, low, i - 1, k);