[算法] [leetcode-215] 数组中的第K个最大元素
215 数组中的第K个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入: [3,2,1,5,6,4], k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
提示:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104
···
class Solution {
public void swapArray(int[] nums, int i, int j) {
if (i == j || i > nums.length || i < 0 || j > nums.length || j < 0) {
return;
}
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
public int findKthLargest(int[] nums, int k) {
if (k <= 0 && k > nums.length) {
return -1;
}
int begin = 0;
int end = nums.length - 1;
// 注意此处是升序排列. 真正获取需要进行反转求下标.
int endIndex = nums.length - k;
while (begin <= end) {
int randomNum = begin + new Random().nextInt(end - begin+1 );
System.out.println(randomNum);
int[] rangeArray = chessSort(nums, begin, end, randomNum);
if (rangeArray[0] <= endIndex && rangeArray[1] >= endIndex) {
return nums[endIndex];
} else if (endIndex < rangeArray[0]) {
end = rangeArray[0] - 1;
} else if (endIndex > rangeArray[1]) {
begin = rangeArray[1] + 1;
}
}
return -1;
}
public int[] chessSort(int[] nums, int begin, int end, int k) {
if (begin > end) {
return new int[]{-1, -1};
}
if (begin == end) {
return new int[]{begin, end};
}
int beginIndex = begin - 1;
int endIndex = end + 1;
int index = begin;
int flagNum = nums[k];
while (index < endIndex) {
if (nums[index] == flagNum) {
index++;
} else if (nums[index] < flagNum) {
// 扩展左边界
beginIndex = beginIndex + 1;
// 交换当前数字
swapArray(nums, index, beginIndex);
// 指标指向下一位
index = index + 1;
} else if (nums[index] > flagNum) {
// 扩展有边界
endIndex = endIndex - 1;
// 交换
swapArray(nums, index, endIndex);
// 指标不动 注意: 当前数字还未进行比较
index = index;
}
}
return new int[]{beginIndex + 1, endIndex - 1};
}
}
···