一、题目描述
返回给定的数组的元素和为奇数的子数组的数目。
示例:
输入:arr = [1,3,5]
输出:4
解释:所有的子数组为 [[1],[1,3],[1,3,5],[3],[3,5],[5]].所有子数组的和为 [1,4,9,3,8,5].
奇数和包括 [1,9,3,5] ,所以答案为 4 。
二、解题方法
方法1:前缀和
以arr = [1, 2, 3, 4, 5, 6, 7]
为例。
访问到index
的位置时,前缀和为奇数的数量为odd
,前缀和为偶数的数量为even
。初始时,odd = 0
,even = 1
,可看作是前面有一个0
。如果当前的子数组的和为奇数,例如[1, 2, 3, 4, 5]
,计算到第五个数为奇数,此时我们只要减去前缀和为偶数的部分即可,即奇 - 偶 = 奇.例如[1, 2, 3, 4, 5] - [1, 2, 3] = [4, 5]
仍然为奇数,或者[1, 2, 3, 4, 5] - [1, 2, 3, 4] = [5]
,再或者[1, 2, 3, 4, 5] - [] = [1, 2, 3, 4, 5]
。也就是说,如果计算到当前位置时前缀和为奇数,那么只需要计算在此之前有多少前缀和是偶数的情况即可。如果当前的子数组的和为偶数,例如[1, 2, 3, 4, 5, 6]
,计算到第六个数为偶数,此时我们只需要减去前缀和为奇数的部分即可,即偶 - 奇 = 奇.
三、code
class Solution {
private:
const int MOD = 1e9 + 7;
public:
int numOfSubarrays(vector<int>& arr) {
int even = 1, odd = 0;
int sum = 0, n = arr.size(), res = 0;
for(int i = 0; i < n; ++i){
sum += arr[i];
if(sum & 1){
++odd;
res = (res + even) % MOD;
}else{
++even;
res = (res + odd) % MOD;
}
}
return res;
}
};