【日常训练】713. 乘积小于 K 的子数组

博客详细介绍了如何利用双指针法(滑动窗口)解决给定整数数组nums中,乘积小于k的连续子数组的个数问题。通过示例解释了算法思路,即通过移动左右指针来更新子数组的乘积,并在乘积大于等于k时左指针右移,从而统计满足条件的子数组数量。代码实现清晰,适用于处理这类数学与数组操作的问题。
摘要由CSDN通过智能技术生成

题目

给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目。

示例 1:
输入:nums = [10,5,2,6], k = 100
输出:8
解释:8 个乘积小于 100 的子数组分别为:[10]、[5]、[2],、[6]、[10,5]、[5,2]、[2,6]、[5,2,6]。
需要注意的是 [10,5,2] 并不是乘积小于 100 的子数组。

示例 2:
输入:nums = [1,2,3], k = 0
输出:0

提示:
1 <= nums.length <= 3 * 104
1 <= nums[i] <= 1000
0 <= k <= 106

代码

package dayLeetCode;

public class dayleetcode713 {
    /**
     *      由于找的是连续子数组的个数,所以可以使用双指针法(滑动窗口)
     *      用变量l,r分别代表子数组的左端和右端,然后将该区间内的数字相乘,查看乘积是否大于k
     *      如果大于k的话就将l左移
     *
     *      如何判断[l,r]中连续子集的个数,以[10,5,2,6],k=100为例
     *      (1)l=0,r=0 tmp=10 1个
     *      (2)l=0,r=1 tmp=50 新增了2个 [5] [10,5]
     *      (3)l=0,r=2 tmp=100 -> l=1,r=2 tmp=10 新增2个 [2][5,2]
     *      (4)l=1,r=3 tmp=60 新增3个 [6][2,6][5,2,6]
     *      通过上述过程我们不难发现每次新增的个数就是 r-l+1
     * @param nums
     * @param k
     * @return
     */

    public int numSubarrayProductLessThanK(int[] nums, int k) {
        // 注意nums中最小为1 当k为0和1时都没有任何子集小于它
        if (k == 0 || k == 1){
            return 0;
        }
        int ans = 0;
        int tmp = 1;
        int l = 0;
        int r = 0;
        for (int i = 0; i < nums.length; i++){
            tmp = tmp * nums[r];
            // l左移
            while (tmp >= k){
                tmp /= nums[l++];
            }
            // 加入[l,r]中子集的个数
            ans += r - l + 1;
            r++;
        }
        return ans;
    }

    public static void main(String[] args) {
        dayleetcode713 obj = new dayleetcode713();
        int[] nums = {10, 5, 2, 6};
        System.out.println(obj.numSubarrayProductLessThanK(nums, 100));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值