题意描述:给定一组元素,求最大的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;
}
}
}