此类问题可以总结为从n(很大)个数中找到m(很小)个最大或最小的数
此类问题的方法有如下几种
1、堆排序
2、位图排序
1、堆排序
如果是找最大数,则从n中选择m个数,建立容量为m的大顶堆,然后剩下的数依次遍历,和堆中的数作比较,大的插入,小的跳过。
此种方法的计算复杂度为n*log(m)。
具体代码(这里的小顶堆使用java的优先队列PriorityQueue实现
)
private static final int nCount = 10;
private static final int mCount = 5;
//实现在n个数中找到最大的前m个数
public static void main(String[] args) {
int[] n = init_n();
Queue<Integer> minQueue = init_big_top_heap(mCount,n);
for (int i = mCount; i < n.length; i++) {
minQueue = compare(n[i],minQueue);
}
//打印最终结果
System.out.println("");
System.out.println("result:");
Iterator iterator = minQueue.iterator();
while(iterator.hasNext()){
System.out.print(iterator.next()+",");
}
}
//初始化大数组
public static int[] init_n(){
//建立一个容量为100w的数组
int[] n = new int[nCount];
Random random = new Random();
for (int i = 0; i < nCount ; i++) {
n[i] = random.nextInt(128);
}
//
System.out.println("打印初始化数组:");
for (int i = 0; i < n.length; i++) {
System.out.print(n[i]+",");
}
return n;
}
//初始化小顶堆
public static Queue init_big_top_heap(int mCount,int[] mArr){
Queue<Integer> minQueue = new PriorityQueue<>();
for (int i = 0; i < mCount; i++) {
minQueue.add(mArr[i]);
}
return minQueue;
}
//数与堆顶元素比较,如果大则插入,小则跳过
public static Queue<Integer> compare(int num,Queue<Integer> minQueue){
if(num>minQueue.peek()){
minQueue.poll();
minQueue.add(num);
}
return minQueue;
}
2、位图排序
思路是:遍历数组中所有元素,找到最大值,然后建立一个以最大值为容量的byte数组用来存放0,1。再次遍历数组,将数组中的元素i对应的byte[i]的值设置为1。得到byte数组之后,从最大值到0开始遍历,如果遍历到的数j对应的byte[j]==1,则放入结果集中。直至结果集满或遍历结束
(需要注意的是,这里没有考虑数据重复的情况)
具体代码(代码是在n个数组中找出最大的m个数
)
private static final int nCount = 10;
private static final int mCount = 5;
private static int[] initArr(){
int n[] = new int[nCount];
Random random = new Random();
for (int i = 0; i < nCount; i++) {
n[i] = random.nextInt(128);
}
System.out.println("打印初始化数组:");
for (int i = 0; i < n.length; i++) {
System.out.print(n[i]+",");
}
return n;
}
public static int[] getTop(int[] inputArray) {
int maxValue = Integer.MIN_VALUE;
//找到数组中的最大值
for (int i = 0; i < inputArray.length; ++i) {
if (maxValue < inputArray[i]) {
maxValue = inputArray[i];
}
}
System.out.println("maxValue:"+maxValue);
//建立位图
byte[] bitmap = new byte[maxValue + 1];
for (int i = 0; i < inputArray.length; ++i) {
int value = inputArray[i];
bitmap[value] = 1;
}
int[] result = new int[mCount];
int index = 0;
//从最大值遍历到0,如果对应位图中值为1,则证明存在,放入结果集中
for (int i = maxValue; i >= 0 & index < result.length; --i) {
if (bitmap[i] == 1) {
result[index++] = i;
}
}
return result;
}
public static void main(String[] args) {
System.out.println("Sort begin...");
long current = System.currentTimeMillis();
int[] result = getTop(initArr());
System.out.println(System.currentTimeMillis() - current);
System.out.println("");
System.out.println("result:");
for (int i = 0; i < result.length; ++i) {
System.out.print(result[i] + ",");
}
}
网友评论