0
点赞
收藏
分享

微信扫一扫

乘积小于K的子数组(滑动窗口问题)

49路末班车 2022-04-13 阅读 29
数据结构

关于双指针问题,前面链表部分介绍过快慢指针的问题,而双指针还有一种情况,也就是滑动指针,正好,最近字节跳动青训营出了类似的题目,正式来自力扣的713题

而青训营中特别要求满足时间复杂度为O(n),

这个题目,我一开始是这样想的,搞两个指针,一个左一个右,开始都位于数组开始的位置,右指针往后走一步,计算一步,直到不满足条件为止,然后left++再次重头再来。

 代码:

int numSubarrayProductLessThanK(int* nums, int numsSize, int k)
{ 
    if(k<=0)
    return 0;
    int left=0;
    int right=0;
    int a=0;
    int count=0;
    while(left<numsSize)
    {
        right=left;
        count=nums[left++];
        for(int right=left;count<k;right++)
        {
            a++;             
            if(right>=numsSize)
            {
                break;
            }
            count*=nums[right];          
        }
    }
    return a;
}

但是这样的代码时间复杂度很明显是O(n2),虽然力扣能够通过,但是,不够厉害,而这时滑动窗口才是最优的算法。

 

 这种算法的奇妙之处在于,如果前面这么多数乘起来还小,那么继续移动right,而如果这些数乘起来超过了那个k,则去移动left,这样,无论是left,还是right,都是只遍历了一次这个数组,时间复杂度自然是2O(N)也可以简化成O(N)

int numSubarrayProductLessThanK(int* nums, int numsSize, int k)
{
    if(k<=1)
        return 0;
    int l=0,r=0,sum=1,cnt=0;
    for(r=0;r<numsSize;r++)
    {
        sum*=nums[r];
        while(sum>=k)
            sum/=nums[l++];
        cnt+=r-l+1;
    }
    return cnt;
}

举报

相关推荐

0 条评论