Subarray Product Less Than K

Subarray Product Less Than K

Question:

请添加图片描述

思路

这道题比较直观的解法就是两个for loop
第一个大loop iterate throught 所有的nums,
里面的loop iterate 一遍所有后续的num并且直接算乘积.
loop 里每做一次乘积, 就可以判断一次< k, 可以直接count
接着等乘积 > k, 就可以break, 从下一个num开始再iterate。
这个方法很直观, 但是效率比较慢 大概是O(N)

解这个题用Slinding Window的话就比较快,
sliding window.
define一个product 用来一直做乘积
right 一直不停的乘以每一个num, 并且每一次乘right num, 都可以进行一次continous subarray的数量增加. 直到product > k, 我们就该缩减左侧的window了。 并且减小乘积. 然后再增加我们最后答案的统计.

举个直观的例子,因为只看代码容易理解不了.

I was SO close to solving this via sliding window, but couldn’t come up with ans += right - left + 1…

For those who are confused, let’s use the example nums = [10,5,2,6]:

If we start at the 0th index, [10], the number of intervals is obviously 1.
If we move to the 1st index, the window is now [10,5]. The new intervals created are [5] and [10,5], so we add 2.
Now, expand the window to the 2nd index: [10,5,2]. The new intervals are [2], [5,2], and [10,5,2], so we add 3.
The pattern should be obvious by now; we add right - left + 1 to the output variable every loop!

同理, 当product > k 的时候, product /=nums[left++]
此时既然能运行到product > k, 就说明right 还有一个num, 还没有适配所有的可能结果<k的乘积.
所以我们要缩减left 把window变小, 从而寻找此时可能和num[right] 形成的subarray.
那么同理这个时候我们还是做 result += right - left +1;
假设按照上面的例子继续写. assume nums[4] = x,
现在的window变成了[5,2,6,x]
那么x就是最新加进window里的. 新的interval 是[x] [6,x] [2,6,x] [5,2,6,x]
so we add 4.

就是这个规律

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        if(k <= 1) { return 0;}
       int result = 0;

        double product = 1;
        int left = 0;
        for (int right = 0; right < nums.length; right++) {
            product *= nums[right];
            while (product >= k && left < nums.length)
                product /= nums[left++];

            // since the product of all numbers from left to right is less than the target therefore,
            // all subarrays from left to right will have a product less than the target too; to avoid
            // duplicates, we will start with a subarray containing only arr[right] and then extend it
            result += right-left + 1;
        }
        return result;   
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值