欢迎来访,清水煮面
联系jacob95047@gmail.com

和为奇数的子数组数目

LeetCode原题链接

题目

给你一个整数数组 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 。

解法

最开始解题时,想着就是如何搜索出各个子串,然后计算子串和,最后用一个set去记录。发现这个思路很直接,但是复杂度很高。
看了题解的解法,感觉是真的妙。官方题解给的思路是逆向求解,题目要求求解子串和为奇数的个数,根据一个数学规律:奇数+奇数=偶数;偶数+奇数=奇数。我们可以转换思路,在遍历到第i位时,我们求前i个数字和,如果这个和是偶数,我们只需要知道前j(j<i)个位置中有多少个和为奇数的子项,那剩下的j + 1到i位置的子项都一定是满足条件的子串数;同理,如果前i个数字和是奇数,我们只需要知道前面j个位置的子项和为偶数的数量。

class Solution {
public:
    int numOfSubarrays(vector<int>& arr) {
        int result = 0;
        int odd = 0;
        int even = 1;
        int sum = 0;
        for (int i = 0; i < arr.size(); ++i)
        {
            sum += arr[i];
            if (sum % 2 == 0)
            {
                result = (result + odd) % 1000000007;
                ++even;
            }
            else
            {
                result = (result + even) % 1000000007;
                ++odd;
            }
        }

        return result;
    }

};
赞(0)
未经允许不得转载(与我联系):清水面 » 和为奇数的子数组数目

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

Warning: error_log(/usr/local/lighthouse/softwares/wordpress/wp-content/plugins/spider-analyser/#log/log-1915.txt): failed to open stream: No such file or directory in /usr/local/lighthouse/softwares/wordpress/wp-content/plugins/spider-analyser/spider.class.php on line 2900