协调性:MaxZeroProduct-复杂性问题

时间:2018-06-21 12:34:40

标签: c algorithm performance time-complexity

我的解决方案的正确性得分为100%,而性能得分为0%。 我只是不知道如何最小化时间复杂度。

问题:

编写函数:

int solution(int A[], int N);

,给定一个由N个正整数组成的数组,返回通过将数组中的三个不同元素相乘而获得的数字的最大尾随零。如果数字在数组中的不同位置,则认为它们是不同的。

例如,给定A = [7、15、6、20、5、10],该函数应返回3(通过取数字15、20和10或20、5的乘积可以获得三个尾随零。和10)。

再举一个例子,给定A = [25,10,25,10,32],该函数应返回4(通过取数字25、25和32的乘积可以获得四个尾随零)。

假设:

  • N是[3..100,000]范围内的整数;
  • 数组A的每个元素都是[1..1,000,000,000]范围内的整数。

复杂度:

  • 预期的最坏情况下的时间复杂度为O(N * log(max(A)));
  • 预期的最坏情况下的空间复杂度为O(N)(不计算输入参数所需的存储空间)。

解决方案:

想法:

  1. 将每个元素分解为5和2的对
  2. 每条 3对成对-这将花费O(N ^ 3)
  3. 找到最小坐标值最大的那对
  4. 返回最小坐标值

代码:

int solution(int A[], int N) {
    int fives = 0, twos = 0, max_zeros = 0;
    int(*factors)[2] = calloc(N, sizeof(int[2])); //each item (x,y) represents the amount of 5's and 2's of the corresponding item in A

    for (int i = 0; i< N; i++) {
        factorize(A[i], &fives, &twos);
        factors[i][0] = fives;
        factors[i][1] = twos;
    }

    //O(N^3)
    for (int i = 0; i<N; i++) {
        for (int j = i + 1; j<N; j++) {
            for (int k = j + 1; k<N; k++) {
                int x = factors[i][0] + factors[j][0] + factors[k][0];
                int y = factors[i][1] + factors[j][1] + factors[k][1];
                max_zeros = max(max_zeros, min(x, y));
            }
        }
    }
    return max_zeros;
}

void factorize(int val, int* fives, int* twos) {
    int tmp = val;  
    *fives = 0, *twos = 0;

    if (val == 0) return;    
    while (val % 5 == 0) { //factors of 5
        val /= 5;
        (*fives)++; 
    }
    while (val % 2 == 0) { //factors of 2
        val /= 2;
        (*twos)++;
    }
} 

我不知道如何在N大小的数组上进行迭代,以便在时间O(N * log(max(A)))中找到最佳的 3 个项目。

2 个答案:

答案 0 :(得分:1)

由于2 ^ 30> 1e9和5 ^ 13> 1e9,所以无论数组有多大,数组中的2和5因子对的限制都是30 * 13 = 390对。这是一个上限(实际数字是213)。

从数组中除每对之外的所有三个代表,那么您的O(N ^ 3)算法可能足够快。

如果仍然不够快,则可以继续进行动态编程,计算P [i,j],这是对元素的2s和5s因数的最大乘积,其索引<= i的形式为x * 2 ^ y * 5 ^ y + j(其中x不能被2或5整除)。然后可以将该表用于第二次动态编程遍历,以查找三个数字最多为0的乘积。

答案 1 :(得分:0)

在现实世界中,我不喜欢这种元思维方式,但是,我们仍然面临一些人为的问题,但存在一些人为的限制...

由于空间复杂度为O(N),因此我们无法提供基于初始输入的动态编程。我们甚至无法绘制N *因素的图。好吧,无论如何我们都能负担得起N * 2的地图,但这基本上就是我们所能提供的。

由于时间复杂度为O(N log(max(A())) ,因此我们可以让自己分解项目并做一些简单的单向方法减少。也许我们可以用计数排序对项目进行排序-有点像N log ^ 2(max(A))进行2索引排序,但是大O会把它排序。

如果我的蜘蛛意识是正确的,我们应该简单地从此counts数组中选取一些内容,并使用1-run through array对其进行润色。诸如最佳计数为2,最佳计数为5之类的东西,然后我们可以列举出找到最佳总产品的其余元素。这只是试探法,但没有骗人的内容!

只需2美分