LeetCode713 乘积小于 K 的子数组-----双指针
题目表述
给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目。
示例:
输入: 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 的子数组。
双指针
-
初始化left、right两个指针,计算[left, right]区间内的数字组成的乘积。
-
right 指针每划过一个数,就将该数字与前面的乘积进行累乘。
-
如果当前乘积 >= k,就开始移动 left 指针并减少累乘的结果,也就是除nums[left]。
-
计算以 right 为右边界所形成的有效子数组的个数(right - left + 1)
时间复杂度:O(N),滑动窗口的时间复杂度分析是这样的:right 指针是一直往右走(不回退),所以 right 最多遍历每个元素一次;而 left 指针是有条件的往右走,最多遍历每个元素一次。所以整体上,nums 中的每个元素最多进出窗口一次,所以时间复杂度最多是 O(2*N),去掉常数项可得 O(N)
class Solution {
public int numSubarrayProductLessThanK(int[] nums, int k) {
int left = 0;
int right = 0;
int sum = 1;
int res = 0;
while(right < nums.length && left <= right){
sum *= nums[right];
while(left <= right && sum >= k){
sum /= nums[left++];
}
res += right - left + 1;
right++;
}
return res;
}
}