leetcode-002-1248. 统计「优美子数组」


怎么样代码更加清晰
代码怎么运算的更快?
怎么样内存更小?
发现自己写代码的速度,也仅仅是打字的速度更快了。代码中还是出现简单的逻辑错误,不能把自己的想法流畅的呈现出来,这是面临的一个瓶颈。
写博客的目的是为了让自己的思路更加的清晰,提高自己的表达能力。


给你一个整数数组 nums 和一个整数 k。

如果某个 连续 子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。

请返回这个数组中「优美子数组」的数目。



示例 1:

输入:nums = [1,1,2,1,1], k = 3
输出:2
解释:包含 3 个奇数的子数组是 [1,1,2,1] 和 [1,2,1,1] 。

示例 2:

输入:nums = [2,4,6], k = 1
输出:0
解释:数列中不包含任何奇数,所以不存在优美子数组。

示例 3:

输入:nums = [2,2,2,1,2,2,1,2,2,2], k = 2
输出:16



提示:

   1 <= nums.length <= 50000
   1 <= nums[i] <= 10^5
   1 <= k <= nums.length

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-number-of-nice-subarrays
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目的思路还算比较好找,我的思路经过三次改变:
最开始,我准备直接在 nums 数组上搜索满足条件的子数列,使用front, end控制出 拥有 k 个奇数的区间,不断移动区间;
后来,灵机一动,如果 nums中的奇数的位置坐标顺序组成一个序列Pos,那么每 k 个相邻的Pos元素,映射在nums上就是一个满足条件的序列,称为初序列。同时,初序列可以延伸到上一个奇数位置 和 下一个奇数位置(中间都是偶数)。因此每 k个Pos元素,计算初序列两边的偶数个数,就能够计算出来子列数:

   int numberOfSubarrays(vector<int>& nums, int k) {
        vector<int> odd_pos;
        for(int i=0; i<nums.size(); i++)
            if(nums[i]%2==1)
                odd_pos.push_back(i);

        int all = 0;
        for(int left=0,right=k-1; right<odd_pos.size(); left++, right++)
        {
            int num_left, num_right;
            if(left==0) //初序列左边的偶数个数
                num_left = odd_pos[left];
            else
                num_left = odd_pos[left] - odd_pos[left-1] -1;

            if(right==odd_pos.size()-1) //初序列右边的偶数个数
                num_right = nums.size()-1-odd_pos[right]else
                num_right = odd_pos[right+1] - odd_pos[right] -1;
            all +=  (num_left+num_right+1)+num_left*num_right;
        }
        return all;
    }

当我看到别人的方法的时候,有一个更简单的思路:奇数为0, 偶数为1, 那么序列就是0和1组成的个数,那么 有多少子列之和为k,就有多少 个 子列,简单而且易懂。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值