如何在100万个整数中 选出最大的10个 java

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在100万个整数中 选出最大的10个 java相关的知识,希望对你有一定的参考价值。

参考技术A 数据量较大,可能无法直接存到一个数组中,可考虑将其分到n个部分,每个部分先跳出此部分的最大的10个数字,然后将这些最大数值在合并到一块,在挑出最大的10个数字即可。本回答被提问者和网友采纳 参考技术B 对一百万数进行分组,比如分成10组,用多线程选出每组的最大一个数字,也可以分成20组
然后再进行比较得出最大的10个数字。
参考技术C 将100万个整数,分成10组,选出每组最大的那个即可 参考技术D 对100万个整数排序,然后选出最后的10个就是了

网易 任2n个整数,从其中选出n个整数,使得选出的n个整数和同剩下的n个整数之和的差最小。

一道网易2015年的内推笔试题实现采用java和c++ ,超详解,外加推理理解;

思路:可以考虑选出的在2n个数中找到n个数使的这n个数的和接近2n个数的总和的1/2.所以我们可以计算出所有n个数有可能的值!

    我们有了上述思路,就可以考虑建立个二维数组int flag[n][m].参数本身可以取0和1,意思是如果存在2n个数中存在n个数的和为m ,则将其置为1;

    首先我们知道flag[0][0]=1;重点是如何一个个推出所有的flag[n][m];

    举个例子flag[1][10];我们就可以在2n中找到1个为10的数就可以了。接着我们要找

    flag[2][14]我们就可以用已有的flag[1][10]推出,在所有的数组中如果能找到一个数num[i]使得flag[2-1][14-num[i]]等于1就可以确定flag[2][14]为1;

    所以我们就可以推广开来。

    if(k>num[i-1]&&flag[j-1][k-num[i-1]]==1){//这里k>num[i-1]是因为我要确保下标不为负!这里用i-1看下面java代码上注释

        flag[j][k]=1;

    }


    

num[i]的取值也需要循环获取所有可能值。(这里i的取值应该是0-2n)

然后我们可以看出这里j本身可以取任何值(这里因为我们只需要算到n个值所以j取值在(i-n)这里为什么是i-n呢因为我们最大只需要到n,而且如果i没取那么多。就按把j=i,通俗话讲就是,你总共的数只有i个,你怎么算其中的i+1个数的和)所以需要个循环。。然后我们还需要所有可能的k值(这里k取值在0 - sum/2,因为我们取这个范围就是为了节省运算时间,没必要算这么多我们的最终目的就是算出n个取值的和,所以没就没必要循环那么多了)。


    根据上述详细分析我们可以写出循环代码:纯手打并不保证出错,真正代码看下面贴出来的

    for(int i=0;i<2*n;i++){//总共有i个数

        for(int j=i>n?n:i;j>0;j++){//在i个数其中的 j个数;

            for(int k=0;k<=sum/2;k++){//j个数总和的值

                if(k>num[i]&&flag[j-1][k-num[i]]==1){

                    flag[j-1][k-num[i]]=1;

                }

            }

        }

    }

    

下面贴出我的C++代码:

#include<stdio.h>
#include<stdlib.h>
int main(){
	int num[] = {1,2,3,4,5,6,7,10};
	int sum = 0;
	int num_length=sizeof(num) / sizeof(num[0]);
	int n = num_length / 2; //n为总和2n的一半
	for (int i = 0; i < num_length; i++){
		sum = sum+num[i];
	}
	/**
	*以下大段是动态创建一个二维数组。
	*/
	int **flag;
	flag = new int*[n+1];
	for (int i = 0; i < n+1; i++){
		flag[i] = new int[sum/2+1];
	}
	for (int i = 0; i < n + 1; i++){
		for (int j = 0; j < sum/2+1; j++){
			flag[i][j] = 0;
		}
	}
	flag[0][0] = 1;

	for (int i = 0; i < 2*n; i++){ //可以当成总共有i个数
		for (int j = i>n ? n : i; j > 0; j--){//然后从中找j个
			for (int k = 0; k <= sum / 2; k++){//找出所有可能的值
				if (k >= num[i] && flag[j-1][k-num[i]]==1){
					flag[j][k] = 1;
				}
			}
		}
			
	}
	for (int i = sum/2+1; i>0 ; i--){
		if (flag[n][i] == 1){
			if (2 * i >= sum){
				printf("差值最小为:%d\n", (2*i - sum));
			}
			if (2 * i < sum){
				printf("差值最小为:%d\n", (sum - 2*i));
			}
			
			break;
		}
	}
	system("pause");
}

下面贴出我的Java代码:

package faceTest;

public class test1 {
   public static void main(String[] args) {
        int num[]={1,2,3,4,5,7,9,10};
        int sum=0;
        for(int i=0;i<num.length;i++){
            sum+=num[i];
        }
        int n=num.length/2;
        boolean flag[][]=new boolean[n+1][sum/2+1];
        for(int i=0;i<=n;i++){
            for(int k=0;k<=sum/2;k++){
                flag[i][k]=false;
            }
        }
        flag[0][0]=true;
        for(int i=0;i<=2*n;i++){
            for(int j=i>n?n:i;j>0;j--){//这里i=0并没有进去。因为j>0的判断。所以num[i-1]才是遍历所有的数!
                for(int k=0;k<=sum/2;k++){
                    if(num[i-1]<=k&&flag[j-1][k-num[i-1]]){//这里因为必须是i-1;只有这样才能访问所有num[i]
                        flag[j][k]=true;
                    }
                }
            }
        }
        for(int i=sum/2;i>0;i--){
            if(flag[n][i]){
                System.out.println("差值为:"+(sum-2*i));
                break;
            }
        }
    }

}

如果有什么疑问,或是本文有不对之处敬请指出!

以上是关于如何在100万个整数中 选出最大的10个 java的主要内容,如果未能解决你的问题,请参考以下文章

求出100个数组里的最大的前十个数最快的算法,c++

CQOI2015选数

有 10 万个乱序的数,如何取前 5 个最大(或最小)的数?丨堆排序链表实现局部排序

自动生成10个整数(1~100),求出生成数组中的最大值和最小值,以及显示排序后的数据。运行效果如图所示

Java 最常用类(前100名)来自一万个开源项目

topK问题最小堆和快排哪个快