/**
* @Class FindKthLargest
* @Description 215. 数组中的第K个最大元素
* 在未排序的数组中找到第 k 个最大的元素。
* 请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
* <p>
* 示例 1:
* 输入: [3,2,1,5,6,4] 和 k = 2
* 输出: 5
* <p>
* 示例 2:
* 输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
* 输出: 4
* 说明:
* 你可以假设 k 总是有效的,且 1 ≤ k ≤ 数组的长度
* @Author
* @Date 2020/6/29
**/
public class FindKthLargest {
}
/**
* 解法1:利用快排的性质,确定最终位置是在(len-k)的元素即可
*/
public static int findKthLargest(int[] nums, int k) {
if (nums == null || nums.length < k) {
return -1;
}
int len = nums.length;
quickSort(nums, 0, len - 1, k);
return nums[len - k];
}
/**
* 快排
*/
private static void quickSort(int[] nums, int start, int end, int k) {
if (start >= end) {
return;
}
int temp = nums[start];
int left = start, right = end;
while (left < right) {
while (left < right && nums[right] >= temp) right--;
while (left < right && nums[left] <= temp) left++;
if (left < right) {
nums[left] = nums[left] + nums[right];
nums[right] = nums[left] - nums[right];
nums[left] = nums[left] - nums[right];
}
}
// 确定temp元素的最终位置
nums[start] = nums[left];
nums[left] = temp;
// 只要确定最终位置是在nums[len-k]上的元素,就不需要再排序其他元素了
if(left == nums.length-k) return;
quickSort(nums, start, left - 1,k);
quickSort(nums, left + 1, end,k);
}
/**
* 也可以采用小顶堆的方式
*/
// 测试用例,测试用例通过不代表提交就通过
public static void main(String[] args) {
int[] nums = new int[]{3, 2, 1, 5, 6, 4};
int k = 2;
int ans = findKthLargest(nums, k);
System.out.println("demo01 result " + ans);
nums = new int[]{3, 2, 3, 1, 2, 4, 5, 5, 6};
k = 4;
ans = findKthLargest(nums, k);
System.out.println("demo02 result " + ans);
nums = new int[]{2,1};
k = 2;
ans = findKthLargest(nums, k);
System.out.println("demo03 result " + ans);
nums = new int[]{3,2,3,1,2,4,5,5,6};
k = 9;
ans = findKthLargest(nums, k);
System.out.println("demo04 result " + ans);
}