寻找N个元素中最大的K个元素解法
来源:互联网 发布:重庆软件测试招聘 编辑:程序博客网 时间:2024/05/18 01:38
问题: 给定N个元素,寻找N个元素中最大的K个元素?
具体解法的算法思想就不详细解答了,详见《编程之美》第140页,下面给出几种解法的Java代码:
解法一:小顶堆原理
/** * 描述: 使用小顶堆来找出n个元素中,最大的k个;结果存放在[1...k],第0个元素位置不用; * * @param array * @param k */public static <T extends Comparable<T>> void heapKmax(T[] array, int k){// 建立K个元素的小顶堆, 元素从1到kfor(int i=k/2; i>0; i--){minHeapAdjust(array, i, k);}T temp;// 对于剩余的元素放入K个元素的小顶堆中for(int i=k+1; i<array.length; i++){if(array[1].compareTo(array[i])<0){temp = array[1];array[1] = array[i];array[i] = temp;minHeapAdjust(array, 1, k);}}}/** * 描述: 小顶堆筛选过程; * * @param array * @param root * @param limit */public static <T extends Comparable<T>> void minHeapAdjust(T[] array, int root, int limit){T tempRoot = array[root];for(int pos = 2*root; pos<=limit; pos*=2){if(pos<limit && array[pos].compareTo(array[pos+1])>0) pos++;if(tempRoot.compareTo(array[pos])<=0){break;}else{array[root] = array[pos];root = pos;}}array[root] = tempRoot;}测试代码:
@Testpublic void testHeapSort(){Integer[] array = new Integer[] {0, 5, 10, 20, 1, 2, 23, -1, 22, 88, 77, 3 };System.out.println("----------排序前--------");for(int i=1; i<array.length; i++){System.out.print(array[i]+"\t");}System.out.println("\n----------排序后--------");heapSort(array);for(int i=1; i<array.length; i++){System.out.print(array[i]+"\t");}}
解法二: 类似快排序;
代码:
private static <T extends Comparable<T>> int partition(T[] array, int low,int high) {T pivot = array[low];while (low < high) {while (low < high && array[high].compareTo(pivot) >= 0) {high--;}if (low < high) {array[low] = array[high];low++;}while (low < high && array[low].compareTo(pivot) <= 0) {low++;}if (low < high) {array[high] = array[low];high--;}}array[low] = pivot;return low;}public static <T extends Comparable<T>> int kmax(T[] array, int start, int end, int k) {if(end-start+1<=k){return start;}if(start<end){int pos = partition(array, start, end);int num = end-pos+1;if(num == k){return pos;}else if(num > k){return kmax(array, pos+1, end, k);}else{return kmax(array, start, pos-1, k-num);}}else{return start;}}测试代码:
@Testpublic void testKmax(String[] args) {Integer[] array = new Integer[] {0, 5, 10, 20, 1, 2, 23, -1, 22, 88, 77, 3 };int pos = kmax(array, 0, array.length-1, 7);for(int i=pos; i<array.length; i++){System.out.print(array[i]+"\t");}System.out.println();quickSort(array, 0, array.length-1);for(int i=0; i<array.length; i++){System.out.print(array[i]+"\t");}}
解法三: 类似二分查找;
代码:
public static int[] binaryKmax(int[] array, int k){int[] kArray = new int[k];// get max & minint max=array[0], min=array[0];for(int i=1; i<array.length; i++){if(array[i]>max){max = array[i];}if(array[i]<min){min = array[i];}}// binary search k max elementint mid = max, m;while(max>=min){mid = min + (int)((max-min)*0.5);m = mMax(array, mid, max);if(m == k){break;}else if(m>k){min = mid+1;}else{max = mid-1;k -= m;}}// get k elementsfor(int i=0, size=0; i<array.length; i++){if(array[i]>=mid){kArray[size++]=array[i];}}return kArray;}/** * 描述:找出[min,max]区间比key不小于key的值的个数; * * @param array * @param key * @param max * @return */private static int mMax(int[] array, int key, int max){int count = 0;for(int i=0; i<array.length; i++){if(array[i]<=max && array[i]>=key){count++;}}return count;}
测试代码:
@Testpublic void testBinaryKmax(){int[] array = new int[] {1, 5, 10, 20, 1, 2, 23, -1, 22, 88, 77, 3 };System.out.println("----------排序前--------");for(int i=0; i<array.length; i++){System.out.print(array[i]+"\t");}System.out.println("\n----------排序后--------");int[] result = binaryKmax(array, 6);for(int i=0; i<result.length; i++){System.out.print(result[i]+"\t");}}
- 寻找N个元素中最大的K个元素解法
- 在N个不同的元素中寻找最大元素
- N个元素取出最大(小)的K个元素
- N个元素取出最大(小)的K个元素
- 题目:N个元素取出最大的K个元素
- 无序n个元素中,寻找第K大的元素 O(n)
- 寻找数组中最小的K个元素
- 找出N个元素的数组中最大的K个数
- n个元素的数组中找出前K个最大数最有效算法O(nlg(k))
- 在一个数组中查找最大的K个元素或者最小的K个元素
- n个元素求m个最大的元素
- 遍历m个元素取k个的递归解法
- 查找n个数中最小的k个元素
- 找n个数字中第k小的元素
- 从N个元素中取k个元素子集的c++实现
- 从N个元素中取k个元素子集的减治法实现
- N个元素数组中第K大元素
- 在两个有序数组中寻找第k个元素
- [+补充]多进程及多线程
- 如何彻底清除MySQL
- [C#.NET][VB.NET] 程式執行時拖曳控制項
- poj 2455 二分+最大流
- NHibernate 3.2或以上的版本就没有 NHibernate.ByteCode.Castle.dll,NHibernate.ByteCode.LinFu.dll, NHibernate.Byt
- 寻找N个元素中最大的K个元素解法
- Linux man 命令后面的圆括号的意义
- fedora下dns的配置
- JAVA里面关于byte数组和String之间的转换问题
- V4L2 深入理解
- Linux命令
- Oracle索引简介
- 操作系统常见面试题总结
- 实战数据结构(10)_单链表的就地排序