【leetcode】【剑指offer Ⅱ】009. 乘积小于 K 的子数组

本文介绍了一种解决正整数数组乘积小于k的子数组计数问题的方法,利用滑动窗口技巧,通过维护左右边界并调整窗口来找到满足条件的子数组。核心思想是当窗口乘积大于等于k时,缩小窗口范围,直到乘积再次小于k。通过实例和代码实现展示了这一算法的应用。
摘要由CSDN通过智能技术生成

问题描述:

  • 给定一个正整数数组 nums 和整数 k,请找出该数组内乘积小于 k 的连续的子数组的个数。

核心思路:

  • 该题仍然是滑动窗口基础应用题,套用模板可以解题:
    • 维护两个指针 ij,其中 i 为窗口左边界,j 为窗口右边界。
    • 外部循环步进右边界 j,在循环内部判断当前窗口是否满足条件,只要条件不满足,则移动左边界 i 直到条件满足。【在该题中只要数组内乘积大于等于 k 就需要缩减窗口】
    • 在循环的最后,此时窗口是满足条件的(满足数组内乘积小于 k),则根据 ij 更新结果。【更新子数组个数】
  • 关键在于如何更新结果,在当前子数组中,此时左边界为 i,右边界为 j,那么此时需要更新的满足条件的子数组个数为 j-i+1
    • 举个例子,假设数组为 nums = {10, 5, 2, 6},而滑动窗口为 j = 1, i = 0 时,窗口内数值为 {10, 5},则符合条件的子数组为 j-i+1 = 2 个,分别为 {5}{10, 5},即 nums[j] = 5 为结尾的满足条件的子数组个数为 2。【注意子数组 {10} 也满足条件,但会在 j = 0 时被发现满足条件并已加入结果中】

代码实现:

class Solution
{
public:
    int numSubarrayProductLessThanK(vector<int>& nums, int k)
    {
        int ans = 0;
        int m = nums.size();
        int i = 0, j = 0;
        int mul = 1;
        while(j < m)
        {
            mul *= nums[j];
            while(i <= j and mul >= k)
                mul /= nums[i++];
            ans += j - i + 1;
            ++j;
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值