713. 乘积小于K的子数组

713. 乘积小于K的子数组

问题

给定一个正整数数组 nums
找出该数组内乘积小于 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的子数组。

说明:

  • 0 < nums.length <= 50000
  • 0 < nums[i] < 1000
  • 0 <= k < 10^6

解法

第一想法是使用双指针一直乘,当结果小于k时,将fast指针与slow指针之间的子数组数量加到结果result中。但是难点在于如何排重。
我们会注意到这样一种规律:

  • fast等于slow时,其实只有一种子数组就是[nums[fast]]
  • fastslow之间的全部子数组,必然包含所有的fast-1slow之间的子数组

此时会发现,fastfast-1子数组的区别仅在于是否包含nums[fast]元素,而包含全部nums[fast]元素的子数组数量为fast-slow+1,这个值,就排除了重复的子数组,result对这个数字进行暂存就可以在循环结束后直接得到数组数量。

当乘积不满足条件时,乘积除以slow指针元素,slow指针前进,

代码

java代码

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        // slow为慢指针,mul为slow与fast之间的乘积,result为满足条件的数组个数.
        int slow = 0, mul = 1, result = 0;
        for (int fast = 0; fast < nums.length; fast++) {
            // fast指针前移,mul计算新的乘积。
            mul *= nums[fast];
            //此时判断mul是否已经大于k了,当大于时,需要除slow元素直到满足条件为止
            while (mul >= k && slow <= fast) {
                mul /= nums[slow++];
            }
            //这里可能会有疑问需不需要判断slow与fast的大小,其实这里不需要判断,前一步如果slow超过fast了,下一轮时,fast会赶上来。而且slow最多比fast多1,两者相减再加一等于0,符合数组数量为0,不用担心减成负数
            result += fast - slow + 1;
        }
        return result;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 线性表中的双指针法是指通过两个指针(游标)来指示线性表中的元素的方法。双指针的使用本身并没有什么神奇之处,但是通过...
    Like_eb56阅读 538评论 0 0
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 9,350评论 0 3
  • 一些概念 数据结构就是研究数据的逻辑结构和物理结构以及它们之间相互关系,并对这种结构定义相应的运算,而且确保经过这...
    Winterfell_Z阅读 6,020评论 0 13
  • 如果一个人焦虑、奔波、不安、上蹿下跳,其实是因为他的存在感没有被满足。就像是生存在驱动动物奔波撕咬一样,对存在感的...
    华筠沁阅读 1,206评论 1 2
  • 十几岁那时候,刚有了朦胧的世界观萌芽但又不太成熟,想不明白宗教的作用是什么。 可能跟影视产品的宣传也有关系,很容易...
    温柔寒江雪阅读 1,005评论 0 2