【问题标题】:Calculate the number of elements of an array that are not divisors of each element计算不是每个元素的除数的数组元素的数量
【发布时间】:2018-06-12 05:12:23
【问题描述】:

我尝试从 Codility 了解问题的解决方案。该问题要求计算不是每个元素的除数的数组元素的数量。完整的描述如下,

You are given a non-empty zero-indexed array A consisting of N integers.
    For each number A[i] such that 0 ≤ i < N, we want to count the number of elements of the array that are not the divisors of A[i]. We say that these elements are non-divisors.
    For example, consider integer N = 5 and array A such that:
        A[0] = 3
        A[1] = 1
        A[2] = 2
        A[3] = 3
        A[4] = 6
    For the following elements:
    A[0] = 3, the non-divisors are: 2, 6,
    A[1] = 1, the non-divisors are: 3, 2, 3, 6,
    A[2] = 2, the non-divisors are: 3, 3, 6,
    A[3] = 3, the non-divisors are: 2, 6,
    A[6] = 6, there aren't any non-divisors.
    Write a function:
    class Solution { public int[] solution(int[] A); }
    that, given a non-empty zero-indexed array A consisting of N integers, returns a sequence of integers representing the amount of non-divisors.
    The sequence should be returned as:
    a structure Results (in C), or
    a vector of integers (in C++), or
    a record Results (in Pascal), or
    an array of integers (in any other programming language).
    For example, given:
        A[0] = 3
        A[1] = 1
        A[2] = 2
        A[3] = 3
        A[4] = 6
    the function should return [2, 4, 3, 2, 0], as explained above.
    Assume that:
    N is an integer within the range [1..50,000];
    each element of array A is an integer within the range [1..2 * N].
    Complexity:
    expected worst-case time complexity is O(N*log(N));
    expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
    Elements of input arrays can be modified.

我也有办法。

// int[] A = {3, 1, 2, 3, 6};
public static int[] solution(int[] A) {

    int[][] D = new int[2 * A.length + 1][2];
    int[] res = new int[A.length];      

        //----- 
        // 0 1 
        // 0 0 
        // 1 -1 
        // 1 -1 
        // 2 -1 
        // 0 0 
        // 0 0 
        // 1 -1 
        // 0 0 
        // 0 0 
        // 0 0 
        // 0 0
        //-----

    for (int i = 0; i < A.length; i++) {
        // D[A[i]][0]++;

        D[A[i]][0] = D[A[i]][0] + 1;
        D[A[i]][1] = -1;
    }


    for (int i = 0; i < A.length; i++){

        if(D[A[i]][1]==-1){

            D[A[i]][1]=0;

            for (int j = 1; j*j <= A[i]; j++) {

                if(A[i] % j == 0) {

                    // D[A[i]][1] = D[A[i]][1] + D[j][0];
                    D[A[i]][1] += D[j][0];

                    if (A[i]/j != j){
                        D[A[i]][1]+= D[A[i]/j][0];
                    }
                }                   
            }
        }
    }

    for (int i = 0; i < A.length; i++) {
        res[i] = A.length - D[A[i]][1]; 
    }

    return res;
}   

当我试图密切关注时,我有点忘记了 for 循环内部发生了什么,

            for (int j = 1; j*j <= A[i]; j++) {

                if(A[i] % j == 0) {

                    // D[A[i]][1] = D[A[i]][1] + D[j][0];
                    D[A[i]][1] += D[j][0];

                    if (A[i]/j != j){
                        D[A[i]][1]+= D[A[i]/j][0];
                    }
                }                   
            }

例如,为什么我们需要检查j*j &lt;= A[i] 之类的条件以及if(A[i] % j == 0) 的含义。我需要解释他们为解决问题而部署的算法。

我不是懒惰,因为我已经找到了解决方案,并且没有尝试。确实,我度过了美好的时光,现在需要帮助。问题难度在网站上列为RESPECTABLE

【问题讨论】:

  • j*j &lt;= A[i]if(A[i] % j == 0) 条件基本上是检查除数:如果你有一个 int n 并且你不知道它是否是素数,你可以搜索从 2sqrt(n) 以最小化迭代。有趣的算法虽然,我会花一些时间试图弄清楚:)

标签: java algorithm performance time-complexity space-complexity


【解决方案1】:

D 数据结构/矩阵使得0th 列和jth 行计算j 在数组A 中出现的次数。换句话说,D[A[j]][0]A[j] 的值在数组中的次数。

在循环之后,1st 列和kth 行计算数组中除以A[k] 的元素数。也就是说D[A[k]][1]是数组中A[k]的除数个数。

最后结果r[j] 就是r[j] = (A.length) - D[A[j]][1]。因为我们想要不是除数的元素的数量。

为什么循环会起作用?

如果A[i] % j == 0 那么我们要做的是计算jA 中出现的次数,然后将其添加到D[A[i]][1]。这就是为什么你有D[A[i]][1] += D[j][0]; 这一行。此外,A[i]/j 也将是一个不同的因素(A[i] = j 除外)。

数学部分证明了集合 { A, B | A * B = N & A

【讨论】:

  • 这很有帮助。非常感谢。
猜你喜欢
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-16
  • 2019-09-30
相关资源
最近更新 更多