leetcode:713.乘积小于k

leetcode:713.乘积小于k,第1张

713. 乘积小于k

来源:力扣(LeetCode)

链接: https://leetcode-cn.com/problems/subarray-product-less-than-k/

给你一个整数数组 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

提示:

  • 1 <= nums.length <= 3 * 104
  • 1 <= nums[i] <= 1000
  • 0 <= k <= 106
解法

滑动窗口法: 遇到这种连续,且有一定的满足条件的数组问题时候,滑动窗口法是比较好的方法。定义两个指针,left与right,都是从起始位置开始进行:

  • 如果right右移,left到right到总乘积仍然小于k,则right继续右移直到不满足上述条件
  • 此时,以left开始,right截止时候到满足次数为 r i g h t − l e f t + 1 right-left+1 rightleft+1
  • 此时left+1,并将总的乘积除以left位置的元素以保证此时left~right之间的元素乘积满足小于k的要求
  • 每次满足要求后,left~right之间的次数都满足 r i g h t − l e f t + 1 right-left+1 rightleft+1
代码实现

python实现

class Solution:
    def numSubarrayProductLessThanK(self, nums: List[int], k: int) -> int:
        # 滑动窗口
        res, left, ji = 0, 0, 1
        for right in range(0, len(nums)):
            ji *= nums[right]
            # 当积超出k的时候ji/nums[left],然后left右移
            while ji >= k and left <= right:
                ji /= nums[left]
                left += 1
            # left->right的情况都符合,并且包含left自己做子数组的时候
            # 每次右指针位移到一个新位置,应该加上 x 种数组组合:
            #  nums[right]
            #  nums[right-1], nums[right]
            #  nums[right-2], nums[right-1], nums[right]
            #  nums[left], ......, nums[right-2], nums[right-1], nums[right]
            # 共有 right - left + 1 种
            res += right - left + 1
        return res

c++实现

class Solution {
public:
    int numSubarrayProductLessThanK(vector<int>& nums, int k) {
        int n = nums.size();
        if(k==0)
        {
            return 0;
        }

        int l = 0;
        int r = 0;
        int prod = 1;
        int count = 0;
        while(r < n)
        {
            prod *= nums[r];
            while( prod >= k && l <= r)
            {
                prod = prod / nums[l];
                l += 1;
            }
            count += r - l + 1;
            r++;
        }
        return count;
    }
};
复杂度分析
  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/873666.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存