欢迎关注本人的微信公众号AI_Engine
国庆归来,依旧精彩。leetcode系列第5篇~
题目:
给定一个正整数数组 nums。找出该数组内乘积小于 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年的作为面试题出现的公司有:旷视科技,阿里,adobe等等。这道题与昨天讲解的题目极为相似(题目传送门:https://www.jianshu.com/p/eddb128b15dd),其具体的做题思路也可以使用双指针。上个题目求的是满足和大于等于s的最短子数组,我之前说过遇到子数组头脑里可以反映出‘前缀’,这道题也是如此。但是与之不同的是一个是前缀和,而另一个是前缀积,这就和题目更加强相关了(看题目,看题目,看题目)。解题的思路还是先对题目进行降维:先求出满足内积小于k的子数组,想到子数组就应该想到区域,想到区域就应该想到边界,想到边界就应该想到flag(指针)(这句话上回书也说过...不要嫌弃)。由于是双指针,所以一左一右进行锁定区域,那么还是初始化左指针left=0,然后利用right遍历整个数组。这次就是计算前缀积了,然后当前缀积小于k时就可以不断扩张区域,即右指针继续向右移动。如果一直都满足内积小于k则相安无事,继续右移。但是一旦前缀积大于等于k时,我们就应该更新区域了。注意:更新区域之前应该先更新前缀积,因为题目说数组中的元素都是正整数,所以这里直接用pre_product / num[left]更新前缀积,然后再讲left左指针向右移,移动到前缀积小于k为止。此时我们利用上述方法就可以求出部分满足条件的子数组,现在我们对题目进行升维:这道题是求满足条件的子数组的个数,所以在扩张的同时就要不断更新子数组的数量,right-left+1的值就是新增的子数组的个数(注意是新增,这个规律可能一下子想不到,但是经过简单的推理就会发现新增数量=right-left+1这个等式关系了)。最后,本道题的执行结果如下所示: