求TopK问题
2016-07-07 21:38
387 查看
题意描述:给定一组元素,求最大的K个(最小的K个)。例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4
解题思路一:当数据量较小时可以对现有元素先排序,再输出前K上元素
解题思路二:利用快排,找到TopK
解题思路三:创建一个大小为k的数据容器来存储最小的k个数字,每次从n个整数中读入一个数字,
如果容器中已有的数字小于k个则直接加入容器,如果容器中已有k个数字,则:
(1)找到最大的那个数字;
(2)可能在容器中删除该最大数;
(3)可能插入一个新的数字;
因此这里实现一个小(大)顶堆
解题思路一:当数据量较小时可以对现有元素先排序,再输出前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; } } }
相关文章推荐
- linux比较两个文件是否一样(linux命令md5sum使用方法)
- LoadRunner监控Tomcat的几种方法
- linux内核中断分析
- 采用dlopen、dlsym、dlclose加载动态链接库【总结】
- 网站web.cofig配置用户的权限
- hadoop入门级总结一:HDFS
- hadoop入门级总结一:HDFS
- Tomcat配置文件常用操作
- 13_03_Linux进程管理之一
- 13_04_Linux进程管理之二
- Linux下的库操作工具-nm、ar、ldd、ldconfig和ld.so
- Hadoop搭建伪分布式 & 上传和下载文件
- linux nohup
- ps top kill
- a configuration error occurred during startup. place verify the preference field whth the prompt:TomcatJDK name:
- Win下Eclipse提交Hadoop程序出错:org.apache.hadoop.security.AccessControlException: Permission denied: user=A
- 常用查看Linux系统信息命令
- linux挂载windows文件夹
- hadoop、spark、zookeeper、hive集群搭建脚本
- 在32位Centos6.4上安装GraphicsMagick