题目:
leetcode 215. 数组中的第K个最大元素
给定整数数组 nums
和整数 k
,请返回数组中第 k
个最大的元素。
请注意,你需要找的是数组排序后的第 k
个最大的元素,而不是第 k
个不同的元素。
你必须设计并实现时间复杂度为 O(n)
的算法解决此问题。
示例 1:
输入: [3,2,1,5,6,4] k=2
输出: 5
题解:
用快速排序的二路快排,即对撞型双指针。
假设数组长度为len,第k个最大元素,即从小到大排序后,下标为len-k(target)的元素值。
利用二路快排的 partition 方法找到中间元素下标,然后与 target 比较,相等则直接返回该下标对应的元素值,若大于 target 则砍掉右边部分,若小于 target 则砍掉左边部分。
代码:
public int findKthLargest(int[] nums, int k) {
int len = nums.length;
int target = len - k;
int left = 0;
int right = len-1;
while(true){
int partition = partition(nums,left,right);
if(partition == target){
return nums[target];
}else if(partition >= target){
right = partition - 1;
}else{
left = partition + 1;
}
}
}
public int partition(int[] arr,int left,int right){
int index = new Random().nextInt(right-left+1)+left;
swap(arr,left,index);
int pivot = arr[left];
int i = left+1;
int j = right;
while(i <= j){
while(i <= j && arr[i] < pivot){
i++;
}
while(i <= j && arr[j] > pivot){
j--;
}
if(i <= j){
swap(arr,i,j);
i++;
j--;
}
}
swap(arr,left,j);
return j;
}
public void swap(int[] arr,int i,int j){
int t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}