【LeetCode】乘积小于 K 的子数组Java题解

103 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

题目描述

给定一个正整数数组 nums和整数 k ,请找出该数组内乘积小于 k 的连续的子数组的个数。


示例 1:

输入: 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的子数组。

示例 2:

输入: nums = [1,2,3], k = 0
输出: 0

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/ZVAVXX
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析

  • 今天的算法题目是数组类型的题目,题目要求该数组内乘积小于 k 的连续的子数组的个数。这句题意的重点是连续子数组,子数组的个数。
  • 分析题目之后,首先可以使用朴素方式求解,使用双重循环,枚举出子数组每一种情况,判断是否符合题目。这种方法直接取出了所有情况,题目只需求解子数组的个数,这种方法的缺点是重复计算比较多。
  • 再次分析这个题目,nums 是整整数数组,我们使用滑动窗口的思想来做这个题目,固定子数组区间[i, j]。当 i 增大的时候, 区间的乘积会变小。使用 prod 记录乘积,当 prod < k 的时候,prod 和数组元素累乘。当 prod >= k 的时候,窗口滑动,i 增加, prod 除以 nums[i],动态更新。减少重复计算。实现代码如下,供参考。

通过代码

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        int ans = 0;
        int n = nums.length;
        int prod = 1, i = 0;
        for (int j = 0; j < n; j++) {
            prod *= nums[j];
            while (i <= j && prod >= k) {
                prod /= nums[i];
                i++;
            }
            ans += j - i + 1;
        }
        return ans;
    }
}

总结

  • 上述算法的时间复杂度是O(n),空间复杂度是O(1)
  • 坚持算法每日一题,加油!