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,让求子数组且满足乘积小于K的个数。既然是子数组,那么必须是连续的,所以肯定不能给数组排序了,这道题好在限定了输入数字都是正数,能稍稍好做一点。博主刚开始用的是暴力搜索的方法来做的,就是遍历所有的子数组算乘积和K比较,两个 for 循环就行了,但是 OJ 不答应。于是上网搜大神们的解法,思路很赞。相当于是一种滑动窗口的解法,维护一个数字乘积刚好小于k的滑动窗口,用变量 left 来记录其左边界的位置,右边界i就是当前遍历到的位置。遍历原数组,用 prod 乘上当前遍历到的数字,然后进行 while 循环,如果 prod 大于等于k,则滑动窗口的左边界需要向右移动一位,删除最左边的数字,那么少了一个数字,乘积就会改变,所以用 prod 除以最左边的数字,然后左边右移一位,即 left 自增1。当确定了窗口的大小后,就可以统计子数组的个数了,就是窗口的大小。为啥呢,比如 [5 2 6] 这个窗口,k还是 100,右边界刚滑到6这个位置,这个窗口的大小就是包含6的子数组乘积小于k的个数,即 [6], [2 6], [5 2 6],正好是3个。所以窗口每次向右增加一个数字,然后左边去掉需要去掉的数字后,窗口的大小就是新的子数组的个数,每次加到结果 res 中即可,参见代码如下:

class Solution {
public:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
if (k <= ) return ;
int res = , prod = , left = ;
for (int i = ; i < nums.size(); ++i) {
prod *= nums[i];
while (left <= i && prod >= k) prod /= nums[left++];
res += i - left + ;
}
return res;
}
};

讨论:这道题其实可有很多种变形,比如当数组的数字有负数和0该怎么做?或者求的不是子数组,而是子序列该怎么做,子序列的话就可以排序啦,当然还是需要都是正数,才有排序的意义,博主觉得如果有负数和0,是不是只能暴力破解了,或者使用 Maximum Product Subarray 中的方法?再有一种的变形就是求子数组或子序列乘积刚好等于k,这就跟 Subarray Sum Equals K 和 Maximum Size Subarray Sum Equals k 这两题中使用的方法类似吧,建立子数组和其乘积之间的映射来快速找到。

欢迎大家在评论区留言讨论!

Github 同步地址:

https://github.com/grandyang/leetcode/issues/713

类似题目:

Maximum Product Subarray

Subarray Sum Equals K

Maximum Size Subarray Sum Equals k

参考资料:

https://leetcode.com/problems/subarray-product-less-than-k/

https://leetcode.com/problems/subarray-product-less-than-k/discuss/108830/C%2B%2B-concise-solution-O(n)

https://leetcode.com/problems/subarray-product-less-than-k/discuss/108861/JavaC%2B%2B-Clean-Code-with-Explanation

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Subarray Product Less Than K 子数组乘积小于K的更多相关文章

  1. 动态规划-子数组乘积小于k的总个数 Subarray Product Less Than K

    2018-09-01 23:02:46 问题求解: 问题求解: 最开始的时候,一眼看过去就是一条 dp 嘛,保存每个数字结尾的长度和,最后求和就好,至于长度如何求,本题中需要用滑动窗口来维护. 很好的 ...

  2. [LeetCode] Subarray Sum Equals K 子数组和为K

    Given an array of integers and an integer k, you need to find the total number of continuous subarra ...

  3. [LeetCode] 560. Subarray Sum Equals K 子数组和为K

    Given an array of integers and an integer k, you need to find the total number of continuous subarra ...

  4. [Swift]LeetCode713. 乘积小于K的子数组 | Subarray Product Less Than K

    Your are given an array of positive integers nums. Count and print the number of (contiguous) subarr ...

  5. [leetcode]523. Continuous Subarray Sum连续子数组和(为K的倍数)

    Given a list of non-negative numbers and a target integer k, write a function to check if the array ...

  6. Java实现 LeetCode 713 乘积小于K的子数组(子集数量+双指针)

    713. 乘积小于K的子数组 给定一个正整数数组 nums. 找出该数组内乘积小于 k 的连续的子数组的个数. 示例 1: 输入: nums = [10,5,2,6], k = 100 输出: 8 解 ...

  7. 【python-leetcode713-双指针】乘积小于k的子数组

    问题描述: 给定一个正整数数组 nums. 找出该数组内乘积小于 k 的连续的子数组的个数. 示例 1: 输入: nums = [10,5,2,6], k = 100输出: 8解释: 8个乘积小于10 ...

  8. JZ009乘积小于k的子数组

    title: 乘积小于k的子数组 题目描述 题目链接:乘积小于k的子数组.剑指offer009 解题思路 注意: 一开始的乘积k值就是小的,随着右边窗口移动才会不断增大 怎么样的条件才能更新左窗口:当 ...

  9. LeetCode 560. Subarray Sum Equals K (子数组之和等于K)

    Given an array of integers and an integer k, you need to find the total number of continuous subarra ...

随机推荐

  1. 关于Linux中文件,链接的一些思考

    在Unix系统中,操作系统为磁盘上的文本与图像,鼠标键盘操作,网络交互等IO操作设计了一组通用API. 使他们被处理的时候可统一用字节流的方式.所以说,除了进程之外,其他的一切均可看做文件. Linu ...

  2. Beta阶段报告

    Beta版测试报告 1. 在测试过程中总共发现了多少Bug?每个类别的Bug分别为多少个? BUG名 修复的BUG 不能重现的BUG 非BUG 没能力修复的BUG 下个版本修复 url乱码 √ 手机端 ...

  3. JAVA使用和操作properties文件

    java中的properties文件是一种配置文件,主要用于表达配置信息,文件类型为*.properties,格式为文本文件,文件的内容是格式是"键=值"的格式,在properti ...

  4. 2017-2018-1 我爱学Java 第三周 作业

    Team Presentation 团队展示 队员学号 队名 团队项目描述 队员风采 团队首次合照 团队的特色描述 团队初步合作 前两周合作过程中的优缺点 如何改进 团队选题 确立,建立和初步熟悉团队 ...

  5. python的PEP8 代码风格指南

    PEP8 代码风格指南 这篇文章原文实际上来自于这里:https://www.python.org/dev/peps/pep-0008/ 知识点 代码排版 字符串引号 表达式和语句中的空格 注释 版本 ...

  6. Scala Option类型

    转载自: Scala 初学者指南, 这里有一系列很棒的文章 类型 Option 可能你已经见过它在 Map API 中的使用:在实现自己的提取器时,我们也用过它, 然而,它还需要更多的解释. 你可能会 ...

  7. JAVA_SE基础——16.方法

    接触过C语言的同学,这小章节很容易接受.Java中的方法是类似与C语言中的函数  功能和调用方法都类似  只不过叫法不一样  因为java是面向对象  c是面向过程    仅仅是叫法不同.. . 看到 ...

  8. [JCIP笔记] (三)如何设计一个线程安全的对象

    在当我们谈论线程安全时,我们在谈论什么中,我们讨论了怎样通过Java的synchronize机制去避免几个线程同时访问一个变量时发生问题.忧国忧民的Brian Goetz大神在多年的开发过程中,也悟到 ...

  9. thinkphp中定义自己的函数

    可以在前台和后台的公共文件夹中common.php中定义自己的函数,这样就可以在控制器中调用,而不需要调用对象了 /** * @name addvtorandp * @author 黄峰1664253 ...

  10. BizTalk 2016 配置 RosettaNet遇到的坑

    本文只针对已经安装好BizTalk 2016 需要在安装RosettaNet加速器的伙伴. IIS配置 权限问题 错误信息 Failed to get IIS metabase property. E ...