您的位置:首页 > 运维架构

Top K问题——基于快速排序

2016-03-26 22:55 483 查看

一、简介

所谓的Top K问题其实就是找数组中最大的前k个值。为此,只要我们能够找到数组中的第k大值,那么Top K问题就会迎刃而解。在此声明一下,本文写的方法肯定不是最好的。不过最近看了几个题,其核心都是找第k大的值。这里,我只是总结下而已。

二、基本思想

1、快速排序一次;

2、利用快速排序一次的函数进行递归搜索;

三、代码

/*
* p[]为待查找数组,L,R分别为数组下标,k表示第k大数
* */
public int findKth(int[] p,int L,int R,int k){
if(L > R || k < 1)//检查输入参数是否合法
return -1;
if(L == R)//如果L等于R说明已找到,直接返回
return p[R];
int temp = quickSort(p,L,R);//进行一次快排,返回下标
if(k+L == temp+1)//如果k+L等于返回的下标加1(L不一定从0开始)
return p[temp];//则直接返回
if(k+L < temp+1)//如果k+L小于返回的下标加1
return findKth(p,L,temp-1,k);//在temp的左边查找第k大数
else//否则,在temp的右边部分查找第k-(temp-L+1)大数。这里,右边的第
//k-(temp-L+1)大数就是整个数组的第k大数
return findKth(p,temp+1,R,k-(temp-L+1));
}
/*
* 一次快速排序
*以p[L]为比较对象,比p[L]大或等于的在其左边,否则在其右边
*/
public int quickSort(int[] p ,int L,int R){
if(L >= R)
return -1;
int i = L;
int j = R;
int temp = p[L];
while(i < j){
while(i < j && p[j] < temp) j--;
if(i < j){
p[i] = p[j];
i++;
}
while(i < j && p[i] > temp) i++;
if(i < j){
p[j] = p[i];
j--;
}
}
p[i] = temp;
//去掉以下两句注释,再将return注释掉,并且将返回值改为void,
//就是一个完整的快速排序
//quickSort(p ,L,i-1);
//quickSort(p ,i+1,R);
return i;
}


三、相关习题

1、数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

2、春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。

给定一个红包的金额数组gifts及它的大小n,请返回所求红包的金额。

测试样例:

[1,2,3,2,2],5

返回:2

经过分析不难看出,如果解决了Top K问题,上述两题就很容易解决了。

以上两题来自互联网

参考

1、寻找最大的K个数

【编程之美】读书笔记:寻找最大的K个数

其实,参考链接中的两个写的比我的好很多,呵呵呵

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: