问题描写叙述:求一个数组的最大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. 【codeforces 508D】The Maths lecture

    [题目链接]:http://codeforces.com/problemset/problem/507/D [题意] 让你找符合这样数字的数的个数: 1.有n个数码 2.某个后缀%k的值为0 3.大于 ...

  2. ASP.NET-HttpPostedFileBase file为null的问题

    MVC使用Ajax.BeginForm上传图片时HttpPostedFileBase file为null,Request.Files获取不到文件,问题分析是页面中存在jquery.unobtrusiv ...

  3. WinServer-AD操作常用powershell命令

    powershell 操作AD常用命令 查询AD中默认的密码策略 Get-ADDefaultDomainPasswordPolicy 查询AD中密码永不过期的用户 Get-ADUser -Filter ...

  4. BZOJ——1602: [Usaco2008 Oct]牧场行走 || 洛谷—— P2912 [USACO08OCT]牧场散步Pasture Walking

    http://www.lydsy.com/JudgeOnline/problem.php?id=1602 || https://www.luogu.org/problem/show?pid=2912 ...

  5. [Angular] Set Metadata in HTTP Headers with Angular HttpHeaders

    Besides sending (or requesting) the actual data to the server API, there’s also often the need to se ...

  6. Python中常见的文件对象内建函数

    文件对象内建方法列表 文件对象的方法 操作 file.close() 关闭文件 file.fileno() 返回文件的描写叙述符(file descriptor.FD,整数值) file.flush( ...

  7. 带输出參数的存储过程的定义,以及在aso.net中调用

    ALTER proc [dbo].[mp_w_RechargePortalPayPal_All] ( @PayPalOrderNo nvarchar(50), --订单号 @nAccountIDFro ...

  8. Unity3D——加入剑痕效果(PocketRPG Trail插件)

    首先非常感谢大家的支持,因为近期项目吃紧,所以更新的速度可能会有点慢!希望大家谅解,当然大家的支持是我最大的动力.我也会尽我所能写出更好的文章,当然因为本人是个新手并且工作的内容也不是unity3D. ...

  9. hdu_4707

    算是水题一道吧,我也没有建树,看别人又用vector,又用bfs,dfs的,对vector不熟,所以就模拟了一下 #include<iostream> #include<string ...

  10. inheritance in kentico

    Visual inheritance http://devnet.kentico.com/docs/7_0/devguide/index.html?visual_inheritance.htm The ...