1、数据结构:一维数组(桶 pos)
- 数组位置 i :代表具体的数值。
- 数组元素个数:代表该位置对应的值在待排序数组中的位置。
2、计数排序(假设给定待排序数组为 nums [2,3,4,7,8,1,2,9],获取第k的值)
- 首先遍历数组 nums,发现最大值为9,将桶的大小设置为10(下标为9的数组长度至少为10)。
- 遍历nums,用桶对各个值进行计数,更新桶 [0,1,2,1,1,0,0,1,1,1]。
- 从下标最大处开始遍历桶:pos[i]=0跳过,k=k-pos[i],当k<=时,i即为所求的第k大的值。
注意点:题目所给num[i]的范围包含负数部分,无法直接用pos的下标i来表示值。
- 在第一次遍历nums的过程中,除最大值外同时记录最小值。
- 桶pos的大小设置为 max-min+2。
- 在pos[v-min]处记录v的个数。
- 最后的返回结果为对应下标 i + min。
代码如下:
Go
func findKthLargest(nums []int, k int) int {
var min, max, res int=nums[0], nums[0], 0
for _, v:=range nums[1:]{
if v>max{ max=v }
if v<min{ min=v }
}
var pos []int = make([]int, max-min+2)
for _, v:=range nums{ pos[v-min]++ }
for i, t:=max-min, k; i>=0; i--{
t=t-pos[i]
if t<=0{
res=i+min
break
}
}
return res
}
Java
class Solution {
public int findKthLargest(int[] nums, int k) {
int max=nums[0];
int min=nums[0];
int res=0;
for(int i=1; i<nums.length; i++){
if(nums[i]>max){ max=nums[i]; }
if(nums[i]<min){ min=nums[i]; }
}
int[] pos=new int[max-min+2];
for(int i=0; i<nums.length; i++){ pos[nums[i]-min]++; }
for(int i=max-min; i>=0; i--){
k=k-pos[i];
if(k<=0){
res=i+min;
break;
}
}
return res;
}
}