【问题标题】:Largest divisible subset in array数组中最大的可整子集
【发布时间】:2017-03-18 11:20:40
【问题描述】:

给定一个数组,任务是找到数组中最大的可整子集。如果对于子集中的每一对 (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;
}

【问题讨论】:

  • 注意:你必须检查你的元素是否不为0,否则你会得到java.lang.ArithmeticException: / by zero
  • 数字可以有多大?可能是O(N * d + N * sqrt(MAX_VAL)),其中d 是输入数组的所有元素的最大除数。
  • 您能否提供更多信息,说明您为何担心时间复杂度(超过代码简单性)?大概您正在考虑该系列中的大量项目?如果是这样,您是否想要包含并行化任务的答案?
  • @sprinter - 准备面试队友 :)
  • 您的经历可能会有所不同,但就个人而言,我从未要求某人在面试工作时通过检查来优化代码性能。我一直要求他们优雅地解决问题或发现错误或提高可读性/可测试性/可维护性。

标签: java arrays algorithm


【解决方案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;
}

【讨论】:

  • 你得到了我的支持。非常感谢您提供的有用提示。
  • 理论上复杂度还是O(n^2)吧?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-04
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多