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

求TopK问题

2016-07-07 21:38 387 查看
题意描述:给定一组元素,求最大的K个(最小的K个)。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4

解题思路一:当数据量较小时可以对现有元素先排序,再输出前K上元素

void topK(int[] array, int k) {
if(array == null || array.length <= 0 || k<=0 || k>array.length)
return;//非法情况处理

Arrays.sort(array);

for(int i=0; i<k; i++)
System.out.print(array[i] + " ");
System.out.println();
}


解题思路二:利用快排,找到TopK

void topK2(int[] array, int low, int high, int k){
if(array == null || array.length <= 0 || k <=0 || k > array.length)
return;

int index = partition2(array, low, high);
if(index == k-1)
return;
else if(index > k-1)
topK2(array, low, index-1, k);
else topK2(array, index+1, high, k);
}
int partition(int[] num, int low, int high){//第一种快排写法
int tmp = num[low];
while(low < high){
while((low < high) && (num[high] >= tmp))
high--;
num[low] = num[high];
while((low < high) && (num[low] <= tmp))
low++;
num[high] = num[low];
}
num[low] = tmp;
return low;
}
int partition2(int[] num, int first, int end){//第二种快排写法
int i = first;
int x = num[end];
for(int j=first; j<end; j++){
if(num[j] < x){
int tmp = num[j];
num[j] = num[i];
num[i] = tmp;
i++;
}
}
num[end] = num[i];
num[i] = x;
return i;
}


解题思路三:创建一个大小为k的数据容器来存储最小的k个数字,每次从n个整数中读入一个数字,

如果容器中已有的数字小于k个则直接加入容器,如果容器中已有k个数字,则:

(1)找到最大的那个数字;

(2)可能在容器中删除该最大数;

(3)可能插入一个新的数字;

因此这里实现一个小(大)顶堆

int[] topK3(int[] num, int k){
int[] heap = BuildHeap(num, k);
for(int i=k; i<num.length; i++)
if(num[i] > heap[0])
insert(heap, num[i]);
return heap;
}
int[] BuildHeap(int[] num, int k){
int[] res = new int[k];
for(int i=0; i<k; i++)
res[i] = num[i];

for(int i=1; i<k; i++){
int child = i;
int parent = (i-1)/2;
int tmp = num[i];
while(parent >= 0 && child != 0 && res[parent] > tmp){
res[child] = res[parent];
child = parent;
parent = (parent - 1)/2;
}
res[child] = tmp;
}
return res;
}
void insert(int[] num, int value){
num[0] = value;
int parent = 0;
while(parent < num.length){
int lchild = 2 * parent + 1;
int rchild = 2 * parent + 2;
int minIndex = parent;
if(lchild < num.length && num[minIndex] > num[lchild])
minIndex = lchild;
if(rchild < num.length && num[minIndex] > num[rchild])
minIndex = rchild;
if(minIndex == parent)
break;
else{
int tmp = num[parent];
num[parent] = num[minIndex];
num[minIndex] = tmp;
parent = minIndex;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: