Leetcode 713 Subarray Product Less Than K

该博客详细介绍了如何解决LeetCode上的713题,即找出数组中乘积小于特定值K的所有连续子数组的数量。博主首先尝试了暴力循环的方法,但发现效率低下,然后调整了思路,从右向左遍历数组,利用前一次计算的乘积来优化计算过程,减少了重复计算。这种方法通过不断更新子数组的右边界并检查乘积是否超过K来提高效率。最终给出的代码实现了这一优化策略,有效地解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Leetcode 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.

思路

最开始做的暴力循环,从每个index开始,找到右边能找的最远的位置,然后一个全部都是1的test case失败,考虑到下一次需要利用上一次的计算结果而不是直接找。
原来的思路其实是先大问题再小问题,是不能利用前者的结果的,就考虑从最靠右侧的index开始,往左加一个数问题扩大,product *= nums[index - 1],这样我们就利用了上一步计算的product来计算当前的product,而此时product是增大的,也就是说原来我的product是从 n u m s [ i ] ⋅ . . . ⋅ n u m s [ j ] nums[i] \cdot ... \cdot nums[j] nums[i]...nums[j],这个时候新的product是从 n u m s [ i − 1 ] ⋅ . . . ⋅ n u m s [ j ] nums[i-1] \cdot ... \cdot nums[j] nums[i1]...nums[j],因为要找到右边的这个最大的j的值,且product递增,这个j不会比上次的j还要大,否则上一次找到的就不是最远成立的j,所以j只会不变或变小。当新的product依然满足小于k时,j不变,此时从i开始的子列有 ( n u m s [ i − 1 ] ) , ( n u m s [ i − 1 ] , n u m s [ i ] ) , . . . , ( n u m s [ i − 1 ] ⋅ . . . ⋅ n u m s [ j ] ) (nums[i - 1]), (nums[i - 1], nums[i]), ..., (nums[i-1] \cdot ... \cdot nums[j]) (nums[i1]),(nums[i1],nums[i]),...,(nums[i1]...nums[j]),共有j-i+1个;当新的product大于等于k时,不断去掉最右边的数,缩小j的值,直到满足要求。
下面的代码是从反方向来的但是思路一样。

代码

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        int res = 0, product = 1, left = 0;
        for (int i = 0; i < nums.length; i++) {
            product *= nums[i];
            while (product >= k && left <= i) {
                product /= nums[left++];
            }
            res += i - left + 1;
        }
        return res;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值