leetcode 713. Subarray Product Less Than K(小于K的子数组乘积)

博客围绕找出元素乘积小于k的子数组个数展开。因数组长度大,遍历所有子数组组合不可行,且子数组连续不能排序。采用滑动窗口方法,固定右边界,滑动左边界,当元素积大于等于k时移除左元素,计算包含右元素的子数组个数,逐步移动右边界求解。

Your are given an array of positive integers nums.

Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k.

Example 1:
Input: nums = [10, 5, 2, 6], k = 100
Output: 8
Explanation: The 8 subarrays that have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6].
Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k.
Note:
0 < nums.length <= 50000.
0 < nums[i] < 1000.
0 <= k < 10^6.

找出子数组,使子数组里所有元素的乘积绝对小于k,返回这样的子数组的个数

思路:
数组长度在50000数量级,遍历所有的子数组组合是不行的。
子数组是连续的,不能改变元素的顺序。因此不能排序。

用slide window的方法
固定住子数组右边界的元素,滑动左边,

当子数组内所有元素乘积>=k时,就把左边的元素滑出去,乘积把左边元素除掉。这时候包含右边元素的子数组个数就是right - left + 1, 这里right,left指的是右边界元素和左边界元素的index,
比如[5,2,6], 包含6的子数组有它本身[6], 向左扩一个[2, 6], 再扩一个[5,2,6], 就是这个子数组的长度right - left + 1

逐步移动右边界即可

注意左边界只需要初始化一次,初始化为0, 后面左边界向右移动后不需要再初始化,
因为,比如[10, 5, 2, 6], 在右边界移动到2时,左边的10要移出,因为10x5x2 >= 100了,那么右边界再向右移时乘积还要再乘6,自然更不需要移掉的10了

    public int numSubarrayProductLessThanK(int[] nums, int k) {
        if(nums == null || nums.length == 0 || k <= 1) {
            return 0;
        }
        
        int n = nums.length;
        int prod = 1;
        int result = 0;
        int left = 0;
    
        for(int i = 0; i < n; i ++) {
            prod *= nums[i];
            while(left <= i && prod >= k) {
                prod /= nums[left];
                left ++;
            }
            result += i-left+1;
        }
        return result;
    }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝羽飞鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值