第K大的数
题目描述
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
示例1
输入 [1,3,5,2,2],5,3
返回值 2
方法一:使用快速排序的思想
1、从大到小排序,每比较完一轮,判断此时走到的数组的索引值i:
2、 i == k - 1,则返回此时索引的数组值
3、 i > k - 1,则第k大的数在此时索引的左边,递归数组左半边
4、i < k - 1,则第k大的数在此时索引的右边,递归数组右半边
方法二:适合海量数据,利用SortedMap
1、利用SortedMap每插入一个数据其结构都是把键按小到大排好序的,
2、map.firstKey为最小的key,map.last为最大的key,
3、先把前面k个数作为key放进map,后面的数逐一和map.firstKey比较,
4、若该数大于map.firstKey,则先remove(map.firstKey),再put(a[i],i)
5、若该数小于或等于map.firstKey,则啥也不做
package 牛客.查找;
/*
*@Author: helen
*@Date: 2021/4/21 12:52
*@Description:
题目描述
有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
示例1
输入 [1,3,5,2,2],5,3
返回值 2
*/
import java.util.SortedMap;
import java.util.TreeMap;
public class 第K大的数 {
public int findKth(int[] a, int n, int k) {
// write code here
int result = QuickFind(a, 0, n - 1, k);
return result;
}
//方法一:
public int QuickFind(int[] a, int start, int end, int k){
int i = start;
int j = end;
while(i < j){
while (i < j && a[i] >= a[j]) j--;
if(i < j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
i++;
}
while (i < j && a[i] >= a[j]) i++;
if(i < j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
j--;
}
}
//此时i = j
if(i < k - 1) {
return QuickFind(a, i + 1, end, k);
}
else if(i > k - 1) {
return QuickFind(a, start, i - 1, k);
}
else {
return a[i];
}
}
//方法二:
public int FindK(int[] a, int n, int k){
SortedMap<Integer, Integer> map = new TreeMap<>();
for (int i = 0; i < n; i++) {
if (i < k)
map.put(a[i], i);
else{
if(a[i] > map.firstKey()) {
map.remove(map.firstKey());
map.put(a[i],i);
}
}
}
return map.firstKey();
}
public static void main(String[] args) {
第K大的数 obj = new 第K大的数();
int[] a = {1,3,5,2,2};
int n = 5;
int k = 3;
int kth = obj.findKth(a, n, k);
System.out.println(kth);
System.out.println(obj.FindK(a, n, k));
}
}