LeetCode 1524. Number of Sub-arrays With Odd Sum(2025/2/25每日一题)

很久没刷leetcode了,今天心血来潮打开看了下,果断刷了每日一题。嗯……Runtime和Memory还可以,宝刀未老嘛嘻嘻……

标题:1524. Number of Sub-arrays With Odd Sum

难度:Medium

题目: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.

举例:输入:arr = [1, 3, 5]。 输出:4

          解释: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.

解题思路:考虑到题目只需要知道和为奇数的子序列的个数,不需要用额外的内存开销来保存子序列。而且根据数据奇偶特性:奇数+奇数=偶数;偶数+奇数=奇数;奇数+偶数=奇数;偶数+偶数=偶数。可以用单指针方法直接遍历数组,遍历到当前位置时,记录以当前位置为结束的所有子序列中奇数和的个数和偶数和的个数。如果当前位置的数字为偶数,则奇数和个数与上一状态相等,偶数和个数加1;如果当前位置的数字为奇数,上一状态奇偶和个数相反,偶数和个数加1。举例说明:

:arr = [1, 2, 3, 4, 5, 6, 7],初始状态奇数和子序列个数odd = 0, 偶数和子序列个数even = 0, 记录最终结果的变量finalOdd = 0;

  1. i = 0:以i=0结束的只有一个子序列 [1], 1为奇数,even不变, odd++。 even = 0, odd = 1. 最后结果finalOdd += odd = 1;
  2. i = 1: 以i=1位置结束的有两个子序列:[1, 2], [2]。2为偶数,odd不变, even+1。因此even = 1 ([2]), odd = 1([1, 2]), finalOdd += odd = 2;
  3. i = 2; 以i = 2位置结束的有三个子序列[1, 2, 3], [2, 3], [3]。3为奇数,则上一状态的子序列([1, 2], [2]) 分别加3之后奇数和变偶数([1, 2] = 3 => [1, 2, 3] = 6), 偶数和变奇数([2] =2 => [2, 3] = 5),因此先交换odd和even的值:swap(odd, even); 因为多了[3], 因此odd需要再加1:odd += 1。odd = 2, even = 1. finalOdd += odd = 4;
  4. i = 3: 与步骤2类似,odd = 2, even = 2, finalOdd = 4+2=6;
  5. i = 4: 与步骤3类似,odd = 3, even = 2, finalOdd = 6 + 3 = 9;
  6. i = 5: 与步骤2类似,odd = 3, even = 3, finalOdd = 9 +3 = 12;
  7. i = 6: 与步骤3类似,odd = 4, even = 3, finalOdd = 12 + 4 = 16.

因此,最后结果为16. 因为题目中说数量可能很大,需要返回mod 1e9+7.因此需要在加之前判断一下

代码C++:

class Solution {
public:
    int numOfSubarrays(vector<int>& arr) {
        int odd = 0, even = 0, maxMod = 1e9 + 7;
        int finalOdd = 0;
        for(int i = 0; i < arr.size(); i++) {
            if (arr[i] % 2 == 0) {
                even ++;
            } else {
                swap(odd, even);
                odd++;
            }
            finalOdd = (finalOdd >= maxMod - odd) ? (finalOdd - maxMod + odd) : (finalOdd + odd);
        }
        return finalOdd;
    }
};

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值