求一个数组的最大k个数(java)
问题描写叙述:求一个数组的最大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)的更多相关文章
- 求一个数组中第K小的数
面试南大夏令营的同学说被问到了这个问题,我的第一反应是建小顶堆,但是据他说用的是快排的方法说是O(n)的时间复杂度, 但是后来经过我的考证,这个算法在最坏的情况下是O(n^2)的,但是使用堆在一般情况 ...
- 求一个数组中最小的K个数
方法1:先对数组进行排序,然后遍历前K个数,此时时间复杂度为O(nlgn); 方法2:维护一个容量为K的最大堆(<算法导论>第6章),然后从第K+1个元素开始遍历,和堆中的最大元素比较,如 ...
- JS求一个数组元素的最小公倍数
求几个数的最小公倍数就是先求出前两个数的最小公倍数,然后再把这个最小公倍数跟第三个数放在一起来求最小公倍数,如此类推... var dbList = []; //两个数的最小公倍数 function ...
- HDU-1695 GCD(求一个区间内与一个数互质的个数)
题意: 给你一个T,是样例的个数,接下来是五个数l1,r1,l2,r2,k 前四个数代表两个区间(l1,r1),(l2,r2)这个题l1=1,l2=1; 取x1属于(1,r1),x2属于(1,r2) ...
- 用递归的方法求一个数组的前n项和
用递归的方法求一个数组的前n项和 public class Demo1 { /* * 用递归的方法求一个数组的前n项和 */ public static void main(String[] args ...
- 算法 - 求一个数组的最长递减子序列(C++)
//************************************************************************************************** ...
- java二分法来求一个数组中一个值的key
package TestArray; import java.util.Arrays; /** * 二分法查找 */ public class Test { public static void ma ...
- 剑指Offer:面试题30——最小的k个数(java实现)
问题描述: 输入n个整数,找出其中最小的k个数 思路1: 先排序,再取前k个 时间复杂度O(nlogn) 下面给出快排序的代码(基于下面Partition函数的方法) public void Quic ...
- 获取一个数组里面第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大的元素呢? 我 ...
随机推荐
- 【codeforces 508D】The Maths lecture
[题目链接]:http://codeforces.com/problemset/problem/507/D [题意] 让你找符合这样数字的数的个数: 1.有n个数码 2.某个后缀%k的值为0 3.大于 ...
- ASP.NET-HttpPostedFileBase file为null的问题
MVC使用Ajax.BeginForm上传图片时HttpPostedFileBase file为null,Request.Files获取不到文件,问题分析是页面中存在jquery.unobtrusiv ...
- WinServer-AD操作常用powershell命令
powershell 操作AD常用命令 查询AD中默认的密码策略 Get-ADDefaultDomainPasswordPolicy 查询AD中密码永不过期的用户 Get-ADUser -Filter ...
- 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 ...
- [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 ...
- Python中常见的文件对象内建函数
文件对象内建方法列表 文件对象的方法 操作 file.close() 关闭文件 file.fileno() 返回文件的描写叙述符(file descriptor.FD,整数值) file.flush( ...
- 带输出參数的存储过程的定义,以及在aso.net中调用
ALTER proc [dbo].[mp_w_RechargePortalPayPal_All] ( @PayPalOrderNo nvarchar(50), --订单号 @nAccountIDFro ...
- Unity3D——加入剑痕效果(PocketRPG Trail插件)
首先非常感谢大家的支持,因为近期项目吃紧,所以更新的速度可能会有点慢!希望大家谅解,当然大家的支持是我最大的动力.我也会尽我所能写出更好的文章,当然因为本人是个新手并且工作的内容也不是unity3D. ...
- hdu_4707
算是水题一道吧,我也没有建树,看别人又用vector,又用bfs,dfs的,对vector不熟,所以就模拟了一下 #include<iostream> #include<string ...
- inheritance in kentico
Visual inheritance http://devnet.kentico.com/docs/7_0/devguide/index.html?visual_inheritance.htm The ...