寻找最大的K个数
来源:互联网 发布:matlab最优化工具箱 编辑:程序博客网 时间:2024/06/06 06:44
问题:查找大量无序元素中最大的K个数。
解法一:该解法是大部分能想到的,也是第一想到的方法。假设数据量不大,可以先用快速排序或堆排序,他们的平均时间复杂度为O(N*logN),然后取出前K个,时间复杂度为O(K),总的时间复杂度为O(N*logN)+O(K).
当K=1时,上面的算法的时间复杂度也是O(N*logN),上面的算法是把整个数组都进行了排序,而原题目只要求最大的K个数,并不需要前K个数有限,也不需要后N-K个数有序。可以通过部分排序算法如选择排序和交换排序,把N个数中的前K个数排序出来,复杂度为O(N*K),选择哪一个,取决于K的大小,在K(K<logN)较小的情况下,选择部分排序。
解法二:(掌握)避免对前K个数进行排序来获取更好的性能(利用快速排序的原理)。
假设N个数存储在数组S中,从数组中随机找一个元素X,将数组分成两部分Sa和Sb.Sa中的元素大于等于X,Sb中的元素小于X。 出现如下两种情况:
(1)若Sa组的个数大于或等于K,则继续在sa分组中找取最大的K个数字 。
(2)若Sa组中的数字小于K ,其个数为T,则继续在sb中找取 K-T个数字 。
一直这样递归下去,不断把问题分解成小问题,平均时间复杂度为O(N*logK)。
解法一代码很简单就不写了。
解法二代码如下:
public class Max_K {public static void main(String[] args){ int a[]={20,100,4,2,87,9,8,5,46,23,234,566,675,11,2424,26}; int K=7; FindKMax(a,0,a.length-1,K) ; for(int i = 0 ; i < K ; i++) { System.out.println(a[i]); }}public static void FindKMax(int a[],int low,int high,int k){ int q; if(low < high) { q=partition(a , low , high); int len = q - low + 1; //表示第几个位置 if(len == k) return; //返回第k个位置 else if(len < k) FindKMax(a , q + 1 , high , k-len); else FindKMax(a , low , q - 1, k); } }public static int partition(int a[], int s,int t) //对数组a从s到t进行一轮快速排序,以第s个元素为基准,将s+1到t元素分列在他的两边。{ int i,j,x; x=a[s]; //取划分元素 i=s; //扫描指针初值 j=t; do { while((a[j]<x)&&i<j) j--; //从右向左扫描,如果是比划分元素小,则不动 if(i<j) a[i++]=a[j]; //大元素向左边移 while((a[i]>=x)&&i<j) i++; //从左向右扫描,如果是比划分元素大,则不动 if(i<j) a[j--]=a[i]; //小元素向右边移 }while(i<j); //直到指针i与j相等 a[i]=x; //划分元素就位 return i;}}结果如下:
234
100
2424
675
87
566
46
0 0
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的k个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的k个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的K个数
- 寻找最大的k个数
- [SCOI2005]繁忙的都市
- 初级UnityDemo全纪录(二):代码篇①
- java的锁机制
- 细说JVM系列:JVM对象的创建、内存布局、访问
- XUtils的BitmapUtils实现分析:
- 寻找最大的K个数
- java笔记--day09--多态和继承的微弱区别
- npm 私服补充
- Android Studio汉化教程
- Maven与Mybatis集成时的问题
- java中native是关键字
- [Android] Start your activity after boot completed
- 连续子数组的最大和
- hibernate-mapping的各种属性配置