找到第一个元素可被第二个元素整除的对数

时间:2015-08-17 06:28:10

标签: algorithm data-structures

假设有一些数字

8, 7, 6, 5, 4, 3, 2

您必须找到(a, b)之前ab之前列表中显示a%b = 0的所有对(8, 4), (8, 2), (6, 3), (6, 2), (4, 2)

这里,这样的对是:

.some

有没有比 O(n 2 更好的算法?

2 个答案:

答案 0 :(得分:1)

你可以预先计算输入中所有可能整数除数的列表= O(n ^ 1.5)

之后迭代输入,同时跟踪一个数字的价值(即它将形成多少对)。

对于输入中的每个数字,您需要对所有除数进行迭代,即O(n ^ 1.5)

所以总复杂度为O(n ^ 1.5),其中n是最大值100000和输入的大小。

class Denominators {                                                        

    public static void main (String[] a) {                                  
        int maxValue = 100000;                                              
        int[] problemSet = {8, 7, 6, 5, 4, 3, 2};                           
        System.out.println (new Denominators().solve(problemSet, maxValue));
    }                                                                       


    int solve (int[] problemSet, int maxValue) {                            
        List<List<Integer>> divisors = divisors(maxValue);                  
        int[] values = new int[maxValue + 1];                               
        int result = 0;                                                     
        for (int i : problemSet) {                                          
            result += values[i];                                            
            for (int d : divisors.get(i)) {                                 
                values[d]++;                                                
            }                                                               
        }                                                                   
        return result;                                                      
    }                                                                       


    private List<List<Integer>> divisors (int until) {                      
        List<List<Integer>> result = new ArrayList<>();                     
        for (int i = 0; i <= until; i++) {                                  
            result.add (new ArrayList<Integer>());                          
        }                                                                   
        for (int i = 1; i * i <= until; i++) {                              
            for (int j = i; j * i <= until ; j++) {                         
                result.get (i * j).add(i);                                  
                if (i != j) result.get (i * j).add(j);                      
            }                                                               
        }                                                                   
        return result;                                                      
    }                                                                       

}

答案 1 :(得分:0)

使用动态编程,这可以通过复杂度O(nlogn)来解决。类似于硬币面额问题。

请参考以下链接获取硬币面额问题解决方案 Coin Denomination problem