乘积小于K的子数组
乘积小于K的子数组
1.静态滑动窗口
- 维护一个mul乘积 对乘积进行 * / 操作
- 当是当滑动窗口的长度len 非常大时, 乘积mul可能会超出数据范围 如果多个 0 ~ 1000 范围的num[i]相乘 可能超出 int 数据范围
- 这种方法非常容易超出int的数据范围 认定为失败的方法
1 | class Solution { |
2.动态滑动窗口
- 从前往后处理所有的
nums[i]
,使用变量i、j代表窗口的左右端点(静态窗口弊端完美解决),使用变量mul记录当前窗口的乘积, - 当
mul>=k
时,我们考虑将左端点i
右移,同时消除左端点元素nums[i]
对mul
的贡献,直到mul>=k
不再满足 - 这样就可以得到每个右端点
nums[i]
的最远左端点nums[j]
, - 进而得知以
nums[i]
为结尾(固定右端点)的合法子数组个数(左端点个数)为i−j+1
1 | class Solution { |
- 时间复杂度:$O(n)$
- 空间复杂度:$O(1)$
3.前缀和+二分查找
前缀和+二分查找,
- 子数组元素乘积小于k即为 $\prod_{n = i}^{j}nums[n] < k$
- 由于在计算子数组乘积时会出现整型溢出的情况,可以将不等式两边取对数得到 $\prod_{n = i}^{j}log(nums[n]) < log(k)$
- 预处理出前缀和数组,
- 枚举子数组的右端点
j
,在prefix数组的[0, j]
区间中通过二分查找 寻找结果
1 |
|
- 时间复杂度:$O(n)$
- 空间复杂度:$O(n)$
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.