[LeetCode] 1524. Number of Sub-arrays With Odd Sum

Problem

https://leetcode.com/problems/number-of-sub-arrays-with-odd-sum/description/

Leetcode - Number of Sub-arrays With Odd Sum

Type - Prefix Sum, Dynamic Programming

Difficulty - Medium

Approach && Solution

Since the length of arr can be up to 10^5, so we can’t solve it naively. (Brute Force solution would take O(n²) → TLE.)

Instead, we can achieve optimal solution with prefix sum.

When sum of range [0, i](inclusive) is odd:

  • It is already odd itself. so count one.

  • If we subtract even prefix sum, the result is odd.

    • If sum of range[0, x] is even, sum of range [0, i] - sum of range[0, x] = sum of range[x+1, i] is odd

Ohterwise(when even)

  • If we subtract odd prefix sum, the result is odd.

    • If sum of range[0, x] is odd, sum of range [0, i] - sum of range[0, x] = sum of range[x+1, i] is odd

variables

  • ans: number of subarrays with odd sum.

  • n: length of arr.

  • pref: prefix sum of [0, i](inclusive).

To solve the problem efficiently, iterate through array once by doing this:

  1. Store the count of odd, even prefix sums before index i.

  2. If prefix sum[0, i] is odd, ans += (count of even prefix sums before i) + 1.
    otherwise, ans += (count of odd prefix sums before i).

Then, return ans % (1e9+7).

Complexity

Time Complexity: O(n) - Iterating Array Once.

Space Complexity: O(1) - No extra data strtuctures. Some primitive variables only.

Code (C++ | Go)

class Solution {
public:
    int numOfSubarrays(vector<int>& arr) {
        long long ans = 0;
        int n = arr.size();
        int pref = 0;

        int oddCount = 0, evenCount = 0;
        for(int i = 0; i < n; i++) {
            pref += arr[i];
            if(pref%2==1) {
                ans += evenCount;
                ans += 1; // can be answer itself
                oddCount++;
            } else {
                ans += oddCount;
                evenCount++;
            }
        }

        return ans % (int)(1e9+7);
    }
};
func numOfSubarrays(arr []int) int {
    ans := 0
    n := len(arr)
    pref := 0

    oddCount, evenCount := 0, 0
    for i := 0; i < n; i++ {
        pref += arr[i]
        if pref%2 == 1 {
            ans += evenCount
            ans += 1
            oddCount++
        } else {
            ans += oddCount
            evenCount++
        }
    }

    return ans % int(1e9+7)
}