概述
给定整数数组 nums 和整数 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 -
提示:
1 <= k <= nums.length <= 104
-104 <= nums[i] <= 104
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/kth-largest-element-in-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
思路一:使用位数组
遍历给定数组,将具体值存进去,然后从高位开始,遍历不为 0 的数组,直到遍历到第 K 个。
注意重复值的情况,若有重复值,需要在此处多计算几次,直到得到第 K 个
class Solution {
public int findKthLargest(int[] nums, int k) {
if (nums.length < k){
return -1;
}
int[] a = new int[(int) Math.pow(10,5) + 1];
for (int i = 0; i < nums.length; i++) {
a[nums[i] + 10000]++; // 由于存在负数,所以都移位保存
}
for (int i = a.length-1; i >= 0; i--) {
if (a[i] == 0){
continue;
} else {
for (int j = 0; j < a[i]; j++) { // 解决重复数字的问题
k = k - 1;
if (k == 0){
return i - 10000;
}
}
}
}
return -1;
}
}
思路二:快速选择
基于快速排序算法,每一次排序结果,都会选择一个元素放到数组的最终位置,位置左边的数都小于该数,右边的数都大于该数。
基于这个原理,如果选择的元素,恰好是在第 K 大的位置,那么直接返回即可,不用排序完成再选择。
class Solution {
public int findKthLargest(int[] nums, int k) {
return quickSelect(nums, 0, nums.length - 1, nums.length - k + 1);
}
public int quickSelect(int[] nums,int low ,int high, int index){
if (low > high){
return -1;
}
int i = low;
int j = high;
int baseVal = nums[i];
while (i < j){
while ( i < j && nums[j] >= baseVal){
j--;
}
while ( i < j && nums[i] <= baseVal){
i++;
}
if (i < j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
nums[low] = nums[i];
nums[i] = baseVal;
if (i == index-1){
return nums[i];
}else if (i > index-1){
return quickSelect(nums,low,i-1,index);
}else {
return quickSelect(nums,i+1,high,index);
}
}
}