Given an array of integers arr
, return the number of subarrays with an odd sum.
Since the answer can be very large, return it modulo 10^9+7
.
Example 1:
Input: arr = [1,3,5] Output: 4 Explanation: All subarrays are [[1],[1,3],[1,3,5],[3],[3,5],[5]] All sub-arrays sum are [1,4,9,3,8,5]. Odd sums are [1,9,3,5] so the answer is 4.
Example 2:
Input: arr = [2,4,6] Output: 0 Explanation: All subarrays are [[2],[2,4],[2,4,6],[4],[4,6],[6]] All sub-arrays sum are [2,6,12,4,10,6]. All sub-arrays have even sum and the answer is 0.
Example 3:
Input: arr = [1,2,3,4,5,6,7] Output: 16
Constraints:
1 <= arr.length <= 10^5
1 <= arr[i] <= 100
题目链接:https://leetcode.com/problems/number-of-sub-arrays-with-odd-sum/
题目大意:求有多少个子区间的和是奇数
题目分析:先求前缀和,统计每个位置之前的前缀和是奇数以及是偶数的个数,根据奇减偶得奇,偶减奇得奇的性质累加一下即可
class Solution {
final int MOD = 1000000007;
public int numOfSubarrays(int[] arr) {
int n = arr.length;
int[] sum = new int[n];
sum[0] = arr[0];
for (int i = 1; i < n; i++) {
sum[i] = sum[i - 1] + arr[i];
}
int[] ocnt = new int[n];
int[] ecnt = new int[n];
if (arr[0] % 2 == 0) {
ecnt[0] = 1;
} else {
ocnt[0] = 1;
}
for (int i = 1; i < n; i++) {
ecnt[i] = ecnt[i - 1] + (sum[i] % 2 == 0 ? 1 : 0);
ocnt[i] = i + 1 - ecnt[i];
}
int ans = ocnt[n - 1];
for (int i = 1; i < n; i++) {
ans = (ans + (sum[i] % 2 == 0 ? ocnt[i - 1] : ecnt[i - 1])) % MOD;
}
return ans;
}
}
不难发现上面的循环都可以合并,合并之后不需要额外声明数组
10ms,时间击败83.45%
class Solution {
final int MOD = 1000000007;
public int numOfSubarrays(int[] arr) {
int sum = 0, ans = 0, ocnt = 0, preocnt = 0;
for (int i = 0; i < arr.length; i++) {
sum += arr[i];
boolean odd = sum % 2 == 1;
ocnt += (odd ? 1 : 0);
ans = (ans + (!odd ? preocnt : i - preocnt)) % MOD;
preocnt = ocnt;
}
ans = (ans + ocnt) % MOD;
return ans;
}
}