找到最长的序列长度,其总和可以被3整除

时间:2015-01-09 18:42:34

标签: algorithm math recursion time-complexity

我需要用O(n)时间复杂度完成练习,但是,我只能用O(n ^ 2)解决方案来解决它。

你有一个数组,你需要计算最长的连续序列,使得它的总和可以被分成3而没有任何余数。例如,对于array {1,2,3,-4,-1),函数将返回4,因为其sum(0)可以划分为3的最长序列为{2,3,-4,-1}

我的解决方案O(n ^ 2)基于 arithmetic progression 。有没有办法用O(n)复杂度做到这一点?

拜托,我只想要一个线索或理论解释。请不要写完整的解决方案:)

4 个答案:

答案 0 :(得分:15)

让我们来看看前缀总和。当且仅当[L, R]时,prefixSum[L - 1] mod 3 = prefixSum[R] mod 3子阵列才会被3除。这个观察给出了一个非常简单的线性解(因为前缀sum mod 3只有3个可能的值,我们可以简单地找到第一个和最后一个)。

例如,如果输入数组是{1,2,3,-4,-1},则前缀和为{0,1,0,0,2,1}。 (由于前缀为空,因此有n + 1个前缀和)。现在,您可以查看第一个和最后一个出现的0,1和2。

答案 1 :(得分:3)

作为非CS人,这很有趣。我的第一种方法就是计算运行总和mod 3.你会得到一个{0,1,2}的序列。现在查找第一个和最后一个0,第一个和最后一个1以及第一个和最后一个2,并比较它们各自的距离......

答案 2 :(得分:3)

遍历数组,总结你的总数。记录模数和为0的第一个位置的位置。另外,记录模数和1的第一个位置的位置。最后,记录模数总和为2的第一个位置的位置。

同样向后做同样的事情,记录模数总和为012的最后位置。这为最长的序列提供了三种可能性 - 您只需检查哪一对距离最远。

答案 3 :(得分:2)

您应用动态编程。 对于每个位置,您计算3个值:

  • 在该位置结束的最长序列,其总和s = 0 mod 3
  • 在该位置结束的最长序列,其总和s = 1 mod 3
  • 在该位置结束的最长序列,其总和s = 2 mod 3

因此,给定位置i的这个值,您可以轻松计算位置i + 1的新值。