1524. 和为奇数的子数组数目
1524. 和为奇数的子数组数目
🟠 🔖 数组 数学 动态规划 前缀和 🔗 力扣 LeetCode
题目
Given an array of integers arr, return the number of subarrays with anodd sum.
Since the answer can be very large, return it modulo 109 + 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^51 <= arr[i] <= 100
题目大意
给你一个整数数组 arr 。请你返回和为 奇数 的子数组数目。
由于答案可能会很大,请你将结果对 10^9 + 7 取余后返回。
示例 1:
输入: 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 。
示例 2 :
输入: arr = [2,4,6]
输出: 0
解释: 所有子数组为 [[2],[2,4],[2,4,6],[4],[4,6],[6]] 。
所有子数组和为 [2,6,12,4,10,6] 。
所有子数组和都是偶数,所以答案为 0 。
示例 3:
输入: arr = [1,2,3,4,5,6,7]
输出: 16
示例 4:
输入: arr = [100,100,99,99]
输出: 4
示例 5:
输入: arr = [7]
输出: 1
提示:
1 <= arr.length <= 10^51 <= arr[i] <= 100
解题思路
前缀和思想:
- 设
prefixSum[i]为arr[0]到arr[i]的前缀和。 - 若
prefixSum[j] - prefixSum[i]为 奇数,则prefixSum[j]和prefixSum[i]必须是 一奇一偶。
- 设
维护前缀奇偶计数:
- 设
oddCount表示前缀和为 奇数 的个数。 - 设
evenCount表示前缀和为 偶数 的个数。 - 遍历
arr,更新sum(前缀和):- 若
sum为 奇数:奇数 - 偶数 = 奇数,即sum - evenSum构成奇数子数组。result += evenCount + 1(包括子数组只有arr[i]一个元素的情况)。oddCount++。
- 若
sum为 偶数:偶数 - 奇数 = 奇数,即sum - oddSum构成奇数子数组。result += oddCount。evenCount++。
- 若
- 设
取模:
- 由于答案可能过大,每次更新
result时都进行mod = 10^9 + 7取模。
- 由于答案可能过大,每次更新
复杂度分析
- 时间复杂度:
O(n),遍历数组一次。 - 空间复杂度:
O(1),仅使用常数级变量。
代码
/**
* @param {number[]} arr
* @return {number}
*/
var numOfSubarrays = function (arr) {
const mod = Math.pow(10, 9) + 7;
let oddCount = 0;
let evenCount = 0;
let result = 0;
let sum = 0;
for (let i = 1; i <= arr.length; i++) {
sum += arr[i - 1];
if (sum % 2 == 1) {
oddCount++;
result = (result + evenCount + 1) % mod;
} else {
evenCount++;
result = (result + oddCount) % mod;
}
}
return result;
};
相关题目
| 题号 | 标题 | 题解 | 标签 | 难度 | 力扣 |
|---|---|---|---|---|---|
| 2098 | 长度为 K 的最大偶数和子序列 🔒 | 贪心 数组 排序 | 🟠 | 🀄️ 🔗 |
