题目
给你一个整数数组 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来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/subarray-product-less-than-k
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
求子数组相关的问题一般可以用滑窗解决。
如果nums的一个子数组乘积小于k,那么这个子数组的所有子数组乘积也都小于k。
问题的核心是如何累加子数组的个数。例如nums = [10,5,2,6], k = 101,[10,5,2]的所有子数组都符合条件,left指针一直指向10,right指向10时,子数组有一个为[10],right移动指向5,增加了子数组[10,5]和[5],即以5结尾的子数组,[10]就不能再计算了,同样,right指向2时,增加了子数组[10,5,2], [5,2]和[2],可以发现,每次增加的个数就是left到right区间的长度。
代码
class Solution {
public int numSubarrayProductLessThanK(int[] nums, int k) {
int n = nums.length;
int left = 0;
int right = 0;
int pro = 1;
int ans = 0;
while (right < n) {
pro *= nums[right];
// 注意left不能超过right,存在pro >= k一直成立的可能
while (left <= right && pro >= k) {
pro /= nums[left];
left++;
}
ans += right - left + 1;
right++;
}
return ans;
}
}