713. 乘积小于K的子数组
给定一个正整数数组 nums
。
找出该数组内乘积小于 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的子数组。
- 时间复杂度:O(n),其中 n 是 nums 数组的长度。循环的时间复杂度为O(n),而 eft 最多移动 n 次,因此总的时间复杂度为 O(n)。
空间复杂度:O(1)。
//滑动窗口法,定住右指针,左指针向他靠拢,<k就是目标数组;但为了去重,只取包含最右数字的组合 r-l+1
//复杂度为啥不是N^2,因为是整体移动,左边指针不需要移动到底,只是在右边的基础上。
func numSubarrayProductLessThanK(nums []int, k int) int {
if k <= 1 {
return 0
}
left, right := 0, 0
sum := 1
res := 0
for right < len(nums) {
sum = sum * nums[right]
//for right, value := range nums {
// sum *= value
for left < right && sum >= k {
sum = sum / nums[left]
left++
}
res += right - left + 1
right++
}
return res
}
//暴力法 func numSubarrayProductLessThanK(nums []int, k int) int { l := len(nums) preAcc := make([]int, l+1) preAcc[0] = 1 for i := 0;i <l;i++ { preAcc[i+1] = preAcc[i] * nums[i] } var result int for i := 1; i <= l;i ++ { for j := 0; j < i;j++ { if preAcc[i] / preAcc[j] < k { //数组太大,会溢出 result++ } } } return result }