[滑动窗口]越短越合法(可转化成越长越合法)
题目链接
题意
给你一个整数数组 nums
和一个整数 k
,请你返回子数组内所有元素的乘积严格小于k
的连续子数组的数目。
首先当ans增加时 我们认为r固定
方法一、转化成越长越合法
思路
算出乘积 ≥ k \ge k ≥k的子数组数量
再用所有子数组数量减去上面算出来的cnt
Code
class Solution {public int numSubarrayProductLessThanK(int[] nums, int k) {if(k <= 1) return 0;int n = nums.length, l = 0, r = 0;long all = (n+1)*n >>1, now = 1, cnt = 0;while(r < n){int x = nums[r++];now *= x;while(now >= k && l < n){int y = nums[l++];now /= y;}cnt += l;//当内部循环结束时,当前窗口无效//但对于左端点在 [0,l] 范围内的 [left,r],都是有效的}return (int)Math.max(0,all - cnt);}
}
方法二
越短越合法的方法
Code
class Solution {public int numSubarrayProductLessThanK(int[] nums, int k) {if(k <= 1) return 0;int n = nums.length, l = 0 ,r = 0, ans = 0;int now = 1;while(r < n){int x = nums[r++];now *= x;while(now >= k){int y = nums[l++];now /= y;}ans += r-l;//内层循环结束时 目前窗口才合法//也就意味着这个窗口内的子数组都合法//右端点r固定 所以l在[l,r]范围内都合法}return ans;}
}