713、乘积小于 K 的子数组
1)题目描述
给你一个整数数组 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 * 10^4
1 <= nums[i] <= 1000
0 <= k <= 10^6
2)分析
双指针,滑窗: 起始点从做到右,找到所有的满足条件的子数组的最大长度,那么这些子数组的子数组都是满足条件的,只需要计算出这些子数组有多少个子数组,累加进结果即可。
- 大于一的数相乘不可能严格小于1,因此当
K<=1
时,直接返回0
; - 两个指针
left
和right
都从第一个元素开始,左指针先不动,右指针逐个右移,并将数组元素逐个累乘,每一次累成都检验累乘结果和k
的关系。若累乘结果小于k
,将区间 [ l e f t , r i g h t ] [left, right] [left,right] 的子数组数量累加进结果;否则,累乘结果除以left
指向的元素,并将left
右移一位; - 区间
[
l
e
f
t
,
r
i
g
h
t
]
[left, right]
[left,right] 的子数组数量为
r
i
g
h
t
−
l
e
f
t
+
1
right-left+1
right−left+1 。因为
right
左边的元素均已经考虑了所有的组合, 所以我们只要考虑含right
的组合, 包含right
的组合数刚好是子数组的长度。
3)C++
代码
class Solution {
public:
int numSubarrayProductLessThanK(vector<int>& nums, int k) {
if(!k||k==1)
return 0;
int tempInte=1;
int res=0;
for(int left=0,right=0;right<nums.size();right++){
tempInte*=nums[right];
while(tempInte>=k)
tempInte/=nums[left++];
res+=right-left+1;
}
return res;
}
};