查找数组的子数组,其总和除以3

时间:2015-01-03 17:13:27

标签: arrays algorithm

我遇到了一个算法问题。请为我提出一些针对以下问题的有效算法

问题是

查找数量的子数组(范围在0< R< N之间),其总和可以被给定的数字整除。

我的方法:

Input:    0  5  3  8  2  1
Sum:   0  0  5  8 16 18 19
Mod 3: 0  0  2  2  1  0  1

否。选择0,1或2的方法是NC2

问题:我是否被要求在某个范围内进行选择,即从2到5,因此阵列将成为:

3  8  2  1

我是否必须重新计算总和和Mod,或者原始的MOd数组会给我一个正确的答案

第二个问题:如果我改变了一个元素,即8 is change to 11,它是怎么回事将是有效的

对于上述问题,我正在考虑使用BIT dp [4] [最大。元素]如果mod是0更新dp [0]如果1更新dp [1]那么如何更新如果VAlue在索引处更改

3 个答案:

答案 0 :(得分:0)

检查一下:

这个子程序找到最大的子阵列,其总和除以3。 它只在阵列上运行一次,没有额外的空间。 这里是c ++代码:

int largest_3_divider_subarray(int* a, int len){

int cum_sum            =  0;    
int index_of_first_one = -1;
int index_of_first_two = -1;
int absolute_maximal   =  0;
int current_maximal    =  0;
bool flag1 = 1, flag2 = 1;

for(int i = 0; i < len; ++i){

    cum_sum += a[i];

    switch (cum_sum%3)
    {
    case 1:
        if(flag1){
            index_of_first_one = i;
            flag1 = 0;
        }else       
            current_maximal = i - index_of_first_one;
        break;

    case 2:
        if(flag2){
            index_of_first_two = i;
            flag2 = 0;
        }else
            current_maximal = i - index_of_first_two;
        break;

    case 0:
        current_maximal = i;
    }

    if(current_maximal > absolute_maximal)
        absolute_maximal = current_maximal;
}

return absolute_maximal + 1;

}

int main() {

int A[]= {6,8,-2,0,9,13,1};
int k = largest_3_divider_subarray(A,7);


return 0;

}

答案 1 :(得分:0)

这可能是一个竞赛问题,但是有一个dp方法。如果你想解决正在运行的竞赛问题,你需要将它与分段树结合起来。

基本理念:

  • 处理以当前字符/数字结尾的子串/子数组的数字之和的%3值。
  • 然后将其作为子问题并尝试使用先前获得的数据获得以不同mod值结束于下一个字符/数字的子阵列的数量。

(dp的特点:我们尝试解决一个子问题,然后使用获得的值,我们尝试解决更大实例的子问题)。

如果要解决codechef

中的运行竞赛问题,则必须与分段树结合使用

有一些很好的教程可用于分段树

答案 2 :(得分:0)

public static int largest_3_divider_subarray(int a[]){

  int cum_sum            =  0;    
  int index_of_first_one = -1;
  int index_of_first_two = -1;
  int absolute_maximal   =  0;
  int current_maximal    =  0;
  boolean flag1 = true, flag2 = true;

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

     cum_sum += a[i];

     switch ((cum_sum%3))
     {
         case 1:
         case -2:
            if(flag1){
             index_of_first_one = i;
             flag1 = false;
            }else       
                current_maximal = i - index_of_first_one;
                break;

          case 2:
          case -1:
            if(flag2){
                index_of_first_two = i;
                flag2 = false;
            }else
                current_maximal = i - index_of_first_two;
                break;

          case 0:
                current_maximal = i+1;
            }

    if(current_maximal > absolute_maximal)
    absolute_maximal = current_maximal;
}

return absolute_maximal ;

}