如何找到最长的连续子阵列的长度,其总和可以被给定的数字整除

时间:2015-08-01 17:47:04

标签: c++ arrays algorithm

我想找到最长的连续子阵列,其总和可以被数字'k'整除。我已经使用具有复杂度o(n ^ 2)的强力来完成它。但是想要为o(n)做.can任何人都建议我在o(n)时间内解决这个问题的有效方法。

例如:     {1 3 1 3 6}

可被3整除的子阵列的最大长度是  2.即{3,6}

另外需要注意的是,k的值在10 ^ 6左右非常大,所以我不能使用前缀sum方法,其中记录每个元素的模数,因为它仅对小数有效。

如此善意地建议我在C中解决这个问题的有效方法。

1 个答案:

答案 0 :(得分:3)

这是一种可以使用的方式:
创建一个summation-modulo k数组,例如。
让数组为:{3,4,10,15,1,4,7}
并且k = 5.然后,求和模数组看起来像:
{3,2,2,2,3,2,4}创建为:{3%5,(3 + 4)%5,(3 + 4 + 10)%5 ...}等等。 现在找到最大指数差异b / w相似的数字。由于k <= 10 ^ 6,您可以使用大小为k的数组轻松完成此操作 在这种情况下,它可以是:{(4-0 = 4) - &gt;索引为3}或{(5-1 = 4) - >索引为2},所以4。

#include<stdio.h>
int main(){
    int n,k,i,j;
    scanf("%d%d",&n,&k);                    //size of the input array 'n' and modular 'k'
    int a[n];
    for(i = 0;i < n;i++)
            scanf("%d",&a[i]);

    //actual processing starts
    //creating summation modulo array in 'a' itself
    a[0] %= k;
    for(i = 1;i < n;i++){
            a[i] = (a[i-1] + a[i]) % k;
    }

    int r[2][k];
    for(i = 0;i < k;i++)
            r[0][i] = r[1][i] = -1;                 //initializing 'r' to -1
    //now evaluating min and max position of any spec no.
    for(i = 0;i < n;i++){
            if(r[0][a[i]] == -1)
                    r[0][a[i]] = i;
            else
                    r[1][a[i]] = i;
    }
    //evaluation of min-max indices complete

    int g = 0;
    //now find max diff if both values are set
    for(i = 0;i < k;i++){
            if(r[0][i] != -1 && r[1][i] != -1 && r[1][i] - r[0][i] > g)
                    g = r[1][i] - r[0][i];
    }
    printf("%d\n",g);               //this is the required answer
}