📌  相关文章
📜  查找所有乘积小于或等于K的子数组(1)

📅  最后修改于: 2023-12-03 15:10:44.747000             🧑  作者: Mango

题目介绍

给定一个正整数数组和一个整数 k ,找到所有乘积小于或等于 k 的连续子数组的个数。

示例
输入: nums = [10, 5, 2, 6], k = 100
输出: 8
解释: 8 种子数组分别为: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6]
题解

题目要求找到所有乘积小于或等于 k 的连续子数组的个数,那么我们可以利用滑动窗口(双指针)的思想,在窗口内枚举所有子数组,并计算乘积大小。当乘积小于或等于 k 时,可以更新答案。如果乘积大于 k ,则移动左指针,缩小窗口大小。由于本题中数组元素皆为正整数,因此可以保证窗口右端点不断向右移动时,乘积值不会减小。

时间复杂度为 O(n)。

以下是 Python 代码实现:

class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
        if not nums:
            return 0
        
        start = 0
        prod = 1
        res = 0
        
        for end in range(len(nums)):
            prod *= nums[end]
            
            while prod >= k and start <= end:
                prod /= nums[start]
                start += 1
            
            res += end - start + 1
        
        return res

以上代码中,我们首先定义了窗口左右端点 start 和 end,prod 存储当前子数组乘积大小,res 统计满足要求的子数组数量。在窗口右端点开始不断向右移动的过程中,我们始终针对新的子数组进行乘积计算,并尝试将左端点不断向右移动,直至乘积大小小于 k。在这个过程中,每次更新 res 都是将区间 [start, end] 中的所有子数组的个数加进去。

Markdown格式的代码
## 题目介绍

给定一个正整数数组和一个整数 k ,找到所有乘积小于或等于 k 的连续子数组的个数。

## 示例

输入: nums = [10, 5, 2, 6], k = 100 输出: 8 解释: 8 种子数组分别为: [10], [5], [2], [6], [10, 5], [5, 2], [2, 6], [5, 2, 6]


## 题解

题目要求找到所有乘积小于或等于 k 的连续子数组的个数,那么我们可以利用滑动窗口(双指针)的思想,在窗口内枚举所有子数组,并计算乘积大小。当乘积小于或等于 k 时,可以更新答案。如果乘积大于 k ,则移动左指针,缩小窗口大小。由于本题中数组元素皆为正整数,因此可以保证窗口右端点不断向右移动时,乘积值不会减小。

时间复杂度为 O(n)。

以下是 Python 代码实现:

```python
class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
        if not nums:
            return 0
        
        start = 0
        prod = 1
        res = 0
        
        for end in range(len(nums)):
            prod *= nums[end]
            
            while prod >= k and start <= end:
                prod /= nums[start]
                start += 1
            
            res += end - start + 1
        
        return res

以上代码中,我们首先定义了窗口左右端点 start 和 end,prod 存储当前子数组乘积大小,res 统计满足要求的子数组数量。在窗口右端点开始不断向右移动的过程中,我们始终针对新的子数组进行乘积计算,并尝试将左端点不断向右移动,直至乘积大小小于 k。在这个过程中,每次更新 res 都是将区间 [start, end] 中的所有子数组的个数加进去。