乘积小于K的子数组

给你一个整数数组 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

来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/subarray-product-less-than-k

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路

我的思路,嗯其实双指针和滑动窗口是差不多的呀,有些时候以滑动窗口理解双指针会更好理解。首先来考虑朴素的做法:使用双重循环遍历所有子数组,计算子数组的乘积是否符合条件。时间复杂度是\(O(n^2)\)。朴素的做法时间复杂度较高的原因在于使用了双重循环,假设外层循环的index为i,内层循环的index为j,每次外层循环时j都会回溯导致时间复杂度较高。那么如何能够使得j不回溯呢?遍历每个一个i开头的子数组并且计算以i开头的子数组符合条件的数目,我们需要找到恰好符合条件的[i,j]使得其乘积恰好小于k,那么以i开头的子数组的数目为j-i+1;当计算i+1开头的子数组数目时并不需要j回溯,将i移除之后[i+1,j]的乘积是必然符合条件的也就是利用了之前的计算结果使得j不需要回溯,只需要将j不断后移,直到找到[i+1,j]使得乘积恰好小于k即可。思路就是这么一个思路,实现上还是有一点细节的,比如nums[i] >= k,那么i开头的子数组都是不可能符合条件的,直接跳过即可;当j == nums.size() -1也就是末尾时,这是i及i往后的所有子数组都是符合条件的,直接计算数目并退出即可。

代码

class Solution {
public:
//朴素做法时间复杂度在于j每次都要回溯
//j不回溯
//遍历每一个i开始的子数组符合条件的数目
//找到恰好没有超出k的[i,j],那么从i开始的子数组数目为j-i+1
//i+1,继续寻找恰好没有超出k的[i+1,j]并计算数目
//j不需要回溯 int numSubarrayProductLessThanK(vector<int>& nums, int k) { int ans = 0; int i = 0,j = 0; int mul = nums[0];
while(i < nums.size())
{
//如果i>=k,那么不可能有i开始的字符串
//直接跳过即可
if(nums[i] >= k)
{
i = i +1;
j = i;
mul = nums[i];
}
//判断从i开始能走多远
while(j < nums.size() && mul < k)
{ j++;
if(j < nums.size()) mul = mul * nums[j];
}
//cout<<i<<" "<<j<<endl; //如果还是小于k,也就是i以及i往后的所有都是小于k的
//直接计算结果就行
if(mul < k)
{
ans += (j - i) * (j - i +1) / 2;
break;
}
//否则i最远能够到[i,j-1],以i开始的数组有j-i个
else
{
ans += j -i;
mul = mul / nums[i];
i++;
}
} return ans;
}
};

乘积小于K的子数组的更多相关文章

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

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

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

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

  3. [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 ...

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

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

  5. [LeetCode] Subarray Product Less Than K 子数组乘积小于K

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

  6. 560. 和为K的子数组

    Q: A: 1.暴力找所有可能的子数组,n^2个子数组,最长长度n,则n ^3. 2.n^2解法 从1~n-1各起点开始,一直找到结尾,n^2 class Solution { public: int ...

  7. 计蒜客-T1271 完美K倍子数组

    如果一个数组满足长度至少是 22 ,并且其中任意两个不同的元素 A_iAi​ 和 A_j (i \not = j)Aj​(i​=j) 其和 A_i+A_jAi​+Aj​ 都是 KK 的倍数,我们就称 ...

  8. 【LeetCode】560. 和为K的子数组

    560. 和为K的子数组 知识点:数组:前缀和: 题目描述 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 输入:nums = [1,1,1], k = 2 ...

  9. Leetcode 560.和为k的子数组

    和为k的子数组 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1 ...

  10. LeetCode 560. 和为K的子数组(Subarray Sum Equals K)

    题目描述 给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数. 示例 1 : 输入:nums = [1,1,1], k = 2 输出: 2 , [1,1] 与 [1,1] ...

随机推荐

  1. DAC双通道模板

    #define DAC_C #include "dac.h" float DAC_DispenseA; float DAC_DispenseB; void MyDAC_Init(v ...

  2. C#中socket的简单使用

    一.Socket的概念Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口. 当两台主机通信是,必须通过Socket连接,Socket ...

  3. Attention:何为注意力机制?

    ​  本文来自公众号"AI大道理" 人类利用有限的注意力资源从大量信息中快速筛选出高价值信息,这是人类在长期进化中形成的一种生存机制,人类视觉注意力机制极大地提高了视觉信息处理的效 ...

  4. iptables(一)基础概念、filter表常用语法规则

    iptables简介 netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火 ...

  5. 清空kafka全部数据

    1.停止机器上的kafka,停止业务系统 docker容器执行命令: docker stop 容器名称 2.删除kafka存储目录(server.properties文件log.dirs配置,默认为& ...

  6. 10 个常用的 JS 工具库,80% 的项目都在用!

    Day.js 一个极简的处理时间和日期的 JavaScript 库,和 Moment.js 的 API 设计保持一样, 但体积仅有2KB. npm install dayjs 基本用法 import ...

  7. JDBC之Connection

    Connection 目录 Connection Java连接MySQL Connection必备知识点 利用JDBC使用Connection 问题一:为什么Java操作数据库的连接不是越多越好 问题 ...

  8. Git中常见的一些问题总结

    Git中常见的一些问题总结 目录 Git中常见的一些问题总结 1.git添加到暂存区的修改,如果不想要了,怎么撤销 2.git添加到本地仓库,如果不想要了,怎么撤销 3.提交代码时发现别人已经提交了( ...

  9. C语言学习---星花与取地址&----以及多级指针

    #include<stdio.h> int main { //对一个表达式加* , 就会对表达式减一级星花*, //如果对表达式取&, 就会加一级* int* p; int** q ...

  10. knife4j 整合springboot

    1.添加依赖 <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife ...