剑指 Offer II 009. 乘积小于 K 的子数组 Java解法

在这里插入图片描述

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        //k <=1 数组中没有满足条件的子数组
        if(k <= 1){
            return 0;
        }
        //l,r代表 左右指针
        int l = 0;
        int r = 0;
        int sum = 1;
        //ans 为满足条件的子数组个数
        int ans = 0;
        while (r < nums.length) {
            //记录乘积
            sum *= nums[r];
            //当大于等于k,左指针右移并把之前左指针的数除掉
            while (sum >= k) {
                sum /= nums[l];
                l++;
            }

            //每次右指针位移到一个新位置,应该加上 x 种数组组合:
            //  nums[right]
            //  nums[right-1], nums[right]
            //  nums[right-2], nums[right-1], nums[right]
            //  nums[left], ......, nums[right-2], nums[right-1], nums[right]
            //共有 right - left + 1 种
            ans += r - l + 1;

            //右指针右移
            r++;
        }
        return ans;
    }
}

举例解释上述代码中 两个难理解的部分

 //当大于等于k,左指针右移并把之前左指针的数除掉
while (sum >= k) {
    sum /= nums[l];
    l++;
}

ans += r - l + 1;
num = [10,2,5,6] k = 100
l,r = 0 sum = 1 ans = 0

l,r
10  2  5  6
sunm *= num[r] = 1*10 = 10
10 < k
本次产生新的满足条件的子数组为 [10]
ans += 0-0+1 = 0+1=1
r++

l   r
10  2  5  6
sum *= num[r] = 10*2 = 20
20 < k
本次产生新的满足条件的子数组为 [2],[10,2]
ans = 1-0+1 = 1+2=3
r++

l      r
10  2  5  6
sum *= num[r] = 20*5=100
100 <= k 满足进入循环条件
while(sum <= k){
	//当sum <=k 成立时 表示此时[l,r]的乘积已经不满足条件 但之前[l,r-1]是满足条件的并已经统计过满足条件的子数组个数
	// sum /= num[l] sum除去l的值 l++ l右移 开始统计另一个区间满足条件的子数组个数
	sum /= num[l] = 100 /10 =10
	l++
}
	l  r
10  2  5  6
10 < k 不满足循环条件 退出while循环
本次产生新的满足条件的子数组为 [5],[2,5]
ans += 2-1+1 = 3+2=5
r++

	l     r
10  2  5  6
sum *= num[r] = 10*6 = 60
60 < k
本次产生新的满足条件的子数组为 [6],[5,6] [2,5,6]
ans += 3-1+1 = 5+3 = 8
r++
r = num.length 循环结束

结果为8
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值