Subarray Product Less Than K

713. Subarray Product Less Than K

Your are given an array of positive integers nums.

Count and print the number of (contiguous) subarrays where the product of all the elements in the subarray is less than k.

Example 1:

Input: nums = [10, 5, 2, 6], k = 100
Output: 8
Explanation: The 8 subarrays that have product less than 100 are: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6].
Note that [10, 5, 2] is not included as the product of 100 is not strictly less than k.

Note:

  • 0 < nums.length <= 50000.
  • 0 < nums[i] < 1000.
  • 0 <= k < 10^6.

1.解析

题目大意,求解乘积小于k的所有连续子序列的个数

2.分析 

这道题还是比较容易看出来的,连续子序列,序列内的元素不要求顺序,完全符合滑动窗口的解法。我刚开始用的是子序列数组和(其实就是滑动窗口的一种类型),但比较难去除重复的情况。参考@Grandyang博主的思路,关键的部分还是在于解决重复情况的代码 res += i - left + 1,个人觉得还是蛮精辟的。left表示窗口的左边界,i表示当前序列的遍历位置,当窗口内的元素乘积大于或等于k时,滑动窗口的左边界;若乘积小于k,根据当前左边界计算窗口内的元素。这样就可以解决重复计算元素的问题。我之前处理的时候,是检测到当窗口内的元素乘积大于或等于k才计算窗口内的子序列个数,这样要考虑去重的问题。

例如: nums = [10,5,2,6,5,3,2], k = 100

当检测到 10 * 5 * 2 == 100,计算子窗口的序列个数:[10] [10, 5] [5]  -------  3  移动左边界为1

继续检测到 5 * 2 * 6 * 5 > 100,计算子窗口的序列个数:[5] [5,2] [2,6] ...  -------  6

可以看到:如果当检测到窗口内的乘积大于k时,在统计,就要考虑去重的问题。所以整体来说,@Grandyang博主解决的思路精辟之处就在于:无论是否检测到窗口内的乘积大于k,都统计子序列的个数,这样就可以解决去重的问题

class Solution {
public:
	int numSubarrayProductLessThanK(vector<int>& nums, int k) {
        if (k <= 1) return 0;
		int left = 0, res = 0, n = nums.size();
		int allProduct = 1;
		for (int i = 0; i < n; ++i) {
			allProduct *= nums[i];
            while (allProduct >= k) allProduct /= nums[left++]; //滑动窗口左边界往右移动
            res += i - left + 1; //统计当前窗口内的子串个数
		}

		return res;
	}
};

[1]https://www.cnblogs.com/grandyang/p/7753959.html 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值