【问题标题】:how to find the length of the longest contiguous subarray whose sum is divisible by a given number [closed]如何找到总和可被给定数字整除的最长连续子数组的长度[关闭]
【发布时间】:2015-08-01 17:47:03
【问题描述】:

我想找到最长的连续子数组,其总和可被数字“k”整除。我已经使用复杂度为 o(n^2) 的蛮力完成了它。但是想要为 o(n) .谁能建议我在 o(n) 时间内解决这个问题的有效方法。

例如: {1 3 1 3 6}

可被 3 整除的子数组的最大长度为 2.即{3,6}

还要注意,这里的 k 值在 10^6 左右非常大,所以我不能使用前缀求和方法,因为它只对小数字有效。

请建议我用 C 语言解决这个问题的有效方法。

【问题讨论】:

  • 你应该在数学堆栈交换网站上问这个问题。这不是一个真正的编程问题。
  • 欢迎来到 StackOverflow,请在询问之前阅读 here

标签: c++ arrays algorithm


【解决方案1】:

这里有一个可以使用的方法:
创建一个求和模 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 在这种情况下,它可以是:{(4-0 = 4) ->index of 3} 或 {(5-1 = 4) ->index of 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
}

【讨论】:

  • 这种方法的运行时复杂度是多少?
  • O(n + k)。您可以亲眼看到,我实际上除了访问每个元素一次之外什么也没做,以创建这个求和模数组。并且要找到最大索引差异 b/w 相等的值,请保留一个大小为 k 的数组,该数组保存其第一次和(更新的)最后一次出现。如果是 c++,您可以使用 pair [],或者使用大小为 [k][2] 的数组。遍历一次就完成了。
  • 有道理。据推测,您也可以通过跟踪最大差异来将其减少到 O(n)。
  • @Oliver,也许吧,但我尽量保持简单。另外,我猜复杂性中的“k”的附加因素并不重要,所以我没有考虑太多。
  • @Shefali,看看我给出的例子和 cmets。我不能更清楚,但如果你愿意,我可以给你代码实现。但我建议你自己做。
猜你喜欢
  • 2012-10-16
  • 2015-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-19
  • 2017-05-29
  • 1970-01-01
  • 2017-06-25
相关资源
最近更新 更多