数组中最大的可分集子集

时间:2017-03-18 11:20:40

标签: java arrays algorithm

给定一个数组,任务是找到数组中最大的可分整子集。如果对于子集中的每对(x,y),子集被称为可分,则x除以y或y除x。

实施例

输入:arr [] = {1,16,7,8,4} 输出:16 8 4 1 在输出子集中,对于每对, 或者第一个元素除以第二个元素 或者先分开。

输入:arr [] = {2,4,3,8} 输出:8 4 2

这是我想出的。时间复杂度为O(n ^ 2)。可以改进吗?

public static int[] largestDivisibleSubset2(int[] a){

    Arrays.sort(a);
    int index=0;
    int maxDivCount=0;
    for(int i=0;i<a.length;i++){
        int currentDivCount=0;
        for (int j=i;j<a.length;j++ ) {
            if(a[j]%a[i]==0){
                currentDivCount++;
            }
        }
        if(currentDivCount>maxDivCount){
            index = i;
            maxDivCount = currentDivCount;
        }
        currentDivCount = 0;
    }
    int[] res = new int[maxDivCount];
    int k=0;
    for(int i=0;i<a.length;i++){
        if(a[i]%a[index]==0){
            res[k++] = a[i];            
        }
    }

    return res;
}

1 个答案:

答案 0 :(得分:1)

在现代多核机器上(以及在Java 8中使用它们的设备大大改进),在优化顺序处理时间之前,通常更容易寻找使用所有核心的方法。如果降低时间复杂度也会降低可读性或可维护性,则尤其如此。

例如,这是解决您的问题的解决方案,它在Java 8中使用并行流,同时决定是否向子集添加值。在我自己的古老机器上,它可以在14秒内找到50,000个随机整数的最大可分集子集(如果我删除parallel方法则为22秒)。显然可以进行优化,但除非有特定原因,否则请先选择清晰度。特别是在采访中: - )

public int[] getSubSet(int... set) {
    int[] largest = new int[0];
    for (int value : set) {
        int[] subset = Arrays.stream(set).parallel()
                .filter(n -> n % value == 0 || value % n == 0).toArray();
        if (subset.length > largest.length)
            largest = subset;
    }
    return largest;
}