以有效的方式计算数组切片的总和

时间:2014-05-21 17:15:20

标签: c++ arrays algorithm

写一个函数:int countZeroSlices(int* arr);返回一个数组中的切片数,它们的总和等于0.例如:arr = {2, -2, 3, 0, 4, -7}满足要求的切片是:(2,-2)(0 ),(3,4,-7),(2,-2,0,3,4,-7)因此该函数应返回“4”切片。

解决方案必须是O(n.Log(n)),其中n是数组的大小

我目前的代码是:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
   vector<int> A{2,-2,0,3,4,-7};

   int sum=0;
   int count=0;
   for(size_t i=0; i<A.size(); i++)
   {
       sum += A[i];
       if(sum==0 || A[i] ==0) count++;
   }
   cout<<count;


   return 0;
}

_ 输出为3,这不是正确的答案。 请注意,我正在检测除中间切片之外的所有切片,例如:(3,4,-7)

1 个答案:

答案 0 :(得分:8)

#include <iostream>
#include <map>
#include <vector>

using namespace std;

int main()
{
   vector<int> A{2,-2,3,0,4,-7};
   map<int, int> partial_sums;
    partial_sums[0] = 1;
    int sum = 0;
    int count = 0;
    for (size_t i = 0; i < A.size(); i++) {
        sum += A[i];
        count += partial_sums[sum];
        partial_sums[sum]++;
    }
   cout << count;
   return 0;
}

说明:数组的每个切片都是两个部分和之间的差异。例如,3 + 4 +( - 7)=(2 +( - 2)+ 0 + 3 + 4 +( - 7)) - (2 +( - 2)+ 0)。要计算位置i处的总和为零结束的切片数量,请注意这样的切片是在位置i处结束的部分和与之前的某些部分之间的差异和。前一个部分和应该具有相同的值,以使结果为零。使用std::map,我们得到O(n log n)。

编辑:修正了一个错误。地图中的初始条目是必要的,以说明空的部分和。