LeeCode( 排序)215_ 数组中的第K个最大元素
题目:
在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:
你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
方法一:
直接调用java的Arrays.sort()
简单粗暴还高效
import java.util.Arrays;
public class 数组中的第K个最大元素 {
public int findKthLargest(int[] nums, int k) {
Arrays.sort(nums);
return nums[nums.length - k];
}
}
方法二:
Arrays.sort()虽然很香但是排序算法还是要会的。
直接写个快速排序,并进行优化。
我们知道快速排序的每一趟扫描都可以确定一个中间值(枢轴元素)pivot的坐标,所以可以优化一下代码,当这趟扫描确定的坐标==arr.length-k时直接返回结果。
(哭了,我的这串代码比Arrays.sort()的效率低了好几倍,看看就好。)
public class 数组中的第K个最大元素 {
public int findKthLargest(int[] nums, int k) {
quickSort(nums,0,nums.length-1,k);
return nums[nums.length-k];
}
private static void quickSort(int[] arr, int start, int end,int k) {
// 递归终止条件
if (start >= end) {
return;
}
// 第一步,找出分区后枢轴的下标,比如[2,1,3],枢轴为2,分区后枢轴的下标为1
int pivotIndex = partition(arr, start, end);
if(pivotIndex==arr.length-k)
return;
// 第二步,对左子数组排序
quickSort(arr, start, pivotIndex - 1,k);
// 第三步,对右子数组排序
quickSort(arr, pivotIndex + 1, end,k);
}
private static int partition(int[] arr, int start, int end) {
//枢轴元素
int pivot = arr[start];
//左指针
int left = start;
int right = end;
while(left < right){
//从右往左扫描
while(left < right && arr[right] >=pivot){
right--;
}
if(left<right){
arr[left] = arr[right];
left++;
}
//从左往右扫描
while(left < right && arr[left] <pivot){
left++;
}
if(left<right){
arr[right] = arr[left];
right--;
}
}
// 扫描完成后,将枢轴元素填入新坑中
arr[left] = pivot;
return left;
}
}