问题描写叙述:求一个数组的最大k个数。如,{1,5,8,9,11,2,3}的最大三个数应该是,8,9,11

问题分析:

1.解法一:最直观的做法是将数组从大到小排序,然后选出当中最大的K个数。可是这种解法,复杂度是O(logn*n),可是有时候并不须要排序,用简单的选择排序。或者是冒泡排序,那么就K轮的交换或者是选择。就能够得出结论,复杂度是O(n*k),当K非常大的时候排序可能是更好的解法。当K小的时候用选择或者是冒泡效率会更加的高。

可是这都是会对前K个数进行排序。所以效率不高。当K非常大的时候,以上两种方法效率都不是非常高。

2.解法二:不正确前K个数进行排序,回顾快排的算法中,那个partition函数。就是随机选择数组中的一个数。把比这个数大的数,放在数组的前面。把比这个数小的数放在数组的

后面,这时想假设找出的随机数。终于位置就是K,那么最大的K个数就找出来了,沿着这个思路思考问题。可是这个函数。最后的索引位置并不一定是K,可能比K大也可能比K小,我们把找出的数组分成两部分sa。sb,sa是大的部分,sb是小的部分,假设sa的长度等于K的话,那么直接返回就是终于结果,假设sa的长度要比K大的话,那么以sa为新的数组,从sa中找出K个最大的数。这时候就把原始数据集降低到的sa。假设sa的长度比K小的话,增加sa中有m个元素,那么m个元素算作是K中元素的一部分,再从sb中找到,k-m个最大的元素,组合起来就是终于的结果,那么这时把问题简化成从sb中找k-m个最大的元素,所以整体来说这是一个递归的过程,尽管复杂大也是O(n*logn)可是,每一次数据量都会降低所以会更加的快。

3.解法三:是利用堆排序,建立一个K阶最大堆,然后数据一个个插入队其中,那么插入队的时间复杂度是O(logK),适合数据量比較大的时候,用堆的效果更加好。

这里给出解法二的代码供大家參考:

public class Main {

	private static void swap(int[] nums,int index1,int index2){
int temp=nums[index1];
nums[index1]=nums[index2];
nums[index2]=temp;
} public static int partition(int[] nums,int start,int end){
int index=new Random().nextInt(nums.length);
int num=nums[index];
swap(nums, index, 0);
int i=start;
int j=end;
while(i<j){
while(i<j&&nums[j]<=num){
j--;
}
if(i<j){
nums[i++]=nums[j];
}
while(i<j&&nums[i]>num){
i++;
}
if(i<j){
nums[j--]=nums[i];
}
}
nums[i]=num;
return i;
} public static int partition(int[] nums){
return partition(nums, 0, nums.length-1); } public static int[] findKmax(int[] nums,int k,int start,int end){
int index=partition(nums,start,end);
int length=index-start+1;
int[] tempMax=Arrays.copyOf(nums, length);
int[] tempMin=new int[nums.length-length];
System.arraycopy(nums, index+1, tempMin, 0, nums.length-length);
if(length>k){
return findKmax(tempMax,k,0,tempMax.length-1);
}else if(length==k){
return tempMax;
}else{
int[] temp2=new int[k];
System.arraycopy(tempMax, 0, temp2, 0, tempMax.length);
int[] temp3=findKmax(tempMin,k-length,0,tempMin.length-1);
System.arraycopy(temp3,0, temp2, index+1, temp3.length);
return temp2;
}
} public static int[] findKmax(int[] nums,int k){
return findKmax(nums, k, 0, nums.length-1);
} public static void print(int[] nums){
for(int i=0;i<nums.length;i++){
System.out.print(nums[i]+" ");
}
} public static void main(String[] args) {
int[] nums={1,5,8,9,11,2,3};
int[] temp=findKmax(nums, 3);
System.out.println("ret:");
print(temp);
} }

求一个数组的最大k个数(java)的更多相关文章

  1. 求一个数组中第K小的数

    面试南大夏令营的同学说被问到了这个问题,我的第一反应是建小顶堆,但是据他说用的是快排的方法说是O(n)的时间复杂度, 但是后来经过我的考证,这个算法在最坏的情况下是O(n^2)的,但是使用堆在一般情况 ...

  2. 求一个数组中最小的K个数

    方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn); 方法2:维护一个容量为K的最大堆(<算法导论>第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如 ...

  3. JS求一个数组元素的最小公倍数

    求几个数的最小公倍数就是先求出前两个数的最小公倍数,然后再把这个最小公倍数跟第三个数放在一起来求最小公倍数,如此类推... var dbList = []; //两个数的最小公倍数 function ...

  4. HDU-1695 GCD(求一个区间内与一个数互质的个数)

    题意: 给你一个T,是样例的个数,接下来是五个数l1,r1,l2,r2,k  前四个数代表两个区间(l1,r1),(l2,r2)这个题l1=1,l2=1; 取x1属于(1,r1),x2属于(1,r2) ...

  5. 用递归的方法求一个数组的前n项和

    用递归的方法求一个数组的前n项和 public class Demo1 { /* * 用递归的方法求一个数组的前n项和 */ public static void main(String[] args ...

  6. 算法 - 求一个数组的最长递减子序列(C++)

    //************************************************************************************************** ...

  7. java二分法来求一个数组中一个值的key

    package TestArray; import java.util.Arrays; /** * 二分法查找 */ public class Test { public static void ma ...

  8. 剑指Offer:面试题30——最小的k个数(java实现)

    问题描述: 输入n个整数,找出其中最小的k个数 思路1: 先排序,再取前k个 时间复杂度O(nlogn) 下面给出快排序的代码(基于下面Partition函数的方法) public void Quic ...

  9. 获取一个数组里面第K大的元素

    如何在O(n)内获取一个数组比如{9, 1, 2, 8, 7, 3, 6, 4, 3, 5, 0, 9, 19, 39, 25, 34, 17, 24, 23, 34, 20}里面第K大的元素呢? 我 ...

随机推荐

  1. 【【henuacm2016级暑期训练】动态规划专题 I】Gargari and Permutations

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 注意这k个序列每个都是排列. 如果在每个序列中都满足y出现在x之后的话. 那么我们从x连一条有向边至y (有一个序列不满足就不连 ( ...

  2. Spring IoC简介及使用

    Spring根本任务 Spring的根本任务就是简化Java开发. 目前许多框架如果要使用他们,就必须要继承或实现这些框架的各种类.这使得框架与我们的程序耦合度过高.由于在我们的程序中加入了过多的框架 ...

  3. angular-Then的用法

    then怎么使用(主要是如何从中提取出我们需要的后台返回的数据):then(fn) 方法中带一个参数,这个参数就是要被执行的函数,并且,这个作为参数的函数本身有一个参数,这个参数就是我们需要的数据,这 ...

  4. [CSS3] All abourt responsive image

    Take few examples: Full size image: The problem for that is it overflow when the screen size is smal ...

  5. 多本Web前端深度修炼书籍(提供网盘下载链接)

    书籍介绍:这本书涵盖了html5新增标签和功能,而且提供了jquerymobile,Phonegap,Sencha Touch框架的介绍和应用,最后还带了一个移动web应用的样例,绝对是移动web开发 ...

  6. XML 解析---dom解析和sax解析

    眼下XML解析的方法主要用两种: 1.dom解析:(Document Object Model.即文档对象模型)是W3C组织推荐的解析XML的一种方式. 使用dom解析XML文档,该解析器会先把XML ...

  7. poj--3984--迷宫问题(bfs+路径记录)

    迷宫问题 Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status D ...

  8. 极客时间 mysql实战45讲下载读 08讲事务到底是隔离的还是不隔离的 笔记

    笔记体会: 1.innodb支持RC和RR隔离级别实现是用的一致性视图(consistent read view) 2.事务在启动时会拍一个快照,这个快照是基于整个库的.基于整个库的意思就是说一个事务 ...

  9. Elasticsearch之重要核心概念(cluster(集群)、shards(分配)、replicas(索引副本)、recovery(据恢复或叫数据重新分布)、gateway(es索引的持久化存储方式)、discovery.zen(es的自动发现节点机制机制)、Transport(内部节点或集群与客户端的交互方式)、settings(修改索引库默认配置)和mappings)

    Elasticsearch之重要核心概念如下: 1.cluster 代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的.es的一个概念就是 ...

  10. SQL控制语句基础

    SQL变量 全局变量: 全局变量是由系统定义和维护的使用两个@作为前缀,不能由用户声明和赋值! 常用的全局变量如下 @@version :获取当前使用的SQL Server版本号 EG: select ...