LeetCode Subarray Product Less Than K 题解 双指针+单调性

题意

给定一个正整数数组和K,数有多少个连续子数组满足:
数组中所有的元素的积小于K.

思路

依旧是双指针的思路
我们首先固定右指针r.
现在子数组的最右边的元素是nums[r].
我们让这个子数组尽可能的长,尽可能的往左边拓展,假设最左边的元素的前一个元素是l.
即子数组(l,r].
显然对于以nums[r]结尾的满足题意的数组个数为 r l r-l rl
对于
( l 1 , r 1 ] , &ThickSpace; ( l 2 , r 2 ] ( r 1 &lt; r 2 ) (l_1,r_1],\;(l_2,r_2] \quad (r_1&lt;r_2) (l1,r1],(l2,r2](r1<r2)
由于数组元素都是正数,易证
l 1 &lt; l 2 l_1 &lt; l_2 l1<l2
举个例子(其实证明也是这个反正的思路):
加入(2,5]和(1,6]同时存在。

  1. (2,5] 第5个数结尾,左边最多到第2个。 ①
  2. (1,6] 第6个数结尾,左边最多到第1个。
    那么换句话第一个数到第五个数的乘积肯定不超过k,那和①这一行的(2,5]矛盾了。
    因此l关于r是非严格单调递增(换句话说不下降)的。
    明白了这一点就可以具体的设计了。

由r快速转移到r+1的状态

假设对于r我们已经求得了(l,r]。
那么对于r+1的问题,我们如何快速转移求解呢?

  1. 更新product,乘以新增的nums[r]
  2. 基于单调性,我们只需从上一步r的l开始验证,如果不符合则l后移

复杂度

T ( N ) = O ( N ) , M ( N ) = O ( 1 ) T(N)=O(N),M(N)=O(1) T(N)=O(N),M(N)=O(1)

结果

(14ms, 80.5%, 52.7MB, 100.00%)

Source Code

class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        int len = nums.length;
        int product = 1;
        int count = 0;
        // (l,r]
        int l = -1, r = 0;
        while (r < len) {
            product *= nums[r];
            while (l < r && product >= k)
                product /= nums[++l];
            count += r - l;
            ++r;
        }
        return count;
    }
}

参考链接

有了思路之后,还参考了GrandYang的博客

全部评论

相关推荐

牛客279957775号:铁暗恋
点赞 评论 收藏
分享
诨号无敌鸭:恭喜佬,但是有一个小问题:谁问你了?我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务