LeetCode713 乘积小于 K 的子数组-----双指针

题目表述

给你一个整数数组 nums 和一个整数 k ,请你返回子数组内所有元素的乘积严格小于 k 的连续子数组的数目。

示例:

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

双指针

  • 初始化left、right两个指针,计算[left, right]区间内的数字组成的乘积。

  • right 指针每划过一个数,就将该数字与前面的乘积进行累乘。

  • 如果当前乘积 >= k,就开始移动 left 指针并减少累乘的结果,也就是除nums[left]。

  • 计算以 right 为右边界所形成的有效子数组的个数(right - left + 1)

时间复杂度:O(N),滑动窗口的时间复杂度分析是这样的:right 指针是一直往右走(不回退),所以 right 最多遍历每个元素一次;而 left 指针是有条件的往右走,最多遍历每个元素一次。所以整体上,nums 中的每个元素最多进出窗口一次,所以时间复杂度最多是 O(2*N),去掉常数项可得 O(N)

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        int left = 0;
        int right = 0;
        int sum = 1;
        int res = 0;
        while(right < nums.length && left <= right){
            sum *= nums[right];
            while(left <= right && sum >= k){
                sum /= nums[left++];
            }
            res += right - left + 1;
            right++;
        }
        return res;
    }
}

posted @ 2022-05-07 23:13  YoungerWb  阅读(20)  评论(0编辑  收藏  举报