【算法】代码随想录、数组——长度最小的子数组、滑动窗口实现

 

  209.长度最小的子数组

解法思想来自代码随想录209.长度最小的子数组

(1)暴力解法

  我们暴力解法直接使用两个for循环,然后不断的遍历寻找符合条件的子序列;

  初始化长度变量length和结果变量result为0和int类型最大数。初始化变量sum为0,表示当前子数组的和。
  第一层循环从0到numsSize-1枚举子数组的起始位置i。第二层循环从i开始到numsSize-1枚举子数组的结束位置j。 在每次循环中将nums[j]加入sum中,表示当前子数组的和。这样子我们通过两重循环,就可以枚举出所有的情况,接下来只要找到符合条件的最小子序列就可以了。
  所有当sum>=target,说明当前子数组的和已经大于等于目标值,是我们满足条件的一个答案,但是不一定是最小的一个。我们求出当前子数组的长度length为j-i+1,并不断的更新result为length和原先result中的较小值。
在这里插入图片描述

  最后返回result。特别地,如果result仍然为int类型最大数,则数组中不存在符合条件的子数组,返回0表示无解。

int minSubArrayLen(int target, int* nums, int numsSize){
    
    
    int length=0;
    int result=INT32_MAX;
    int i=0,j=0;
    int sum=0;
   
    for(i=0;i<numsSize;i++)
    {
    
    
        sum=0;
        for(j=i;j<numsSize;j++)
        {
    
    
            sum+=nums[j];
            if(sum>=target)
            {
    
    
                length=(j-i+1);
                result=length<result?length:result;
            }
        }
    }
 
    return result==INT32_MAX?0:result;
}

由于时间复杂度较高,leetcode只能通过18/20的用例。

时间复杂度:O(n^2)
空间复杂度:O(1)

(2)滑动窗口

代码随想录详解

  滑动窗口类型于双指针法,我们可以不断的调节子序列的起始位置和终止位置,从而得出长短最小的子数列长度。

  初始化变量sum为0,表示当前子数组的和。初始化变量result为int类型的最大值,表示暂时解为0。初始化变量length为0,表示当前子数组长度。初始化双指针i和j为0,i表示当前子数组的右边界,j表示当前子数组的左边界。
  第一层循环从0到numsSize-1枚举子数组的右端点i。在每次循环中将nums[i]加入sum中,表示当前子数组的和。
  使用while循环,如果sum>=target,则说明当前子数组的和已经大于等于目标值。我们先将所满足要求的一个答案储存以便之后不断比较,此时需要开始缩短左边界,寻找更短的子数组。循环条件为sum>=target。
  将当前子数组的长度length设为i-j+1,并更新result为length和原先result中的较小值。将nums[j]从sum中减去,表示缩小左边界。将左指针j指向下一个元素。
  循环结束后返回result。如果result仍然为无穷大,则数组中不存在符合条件的子数组,返回0。

int minSubArrayLen(int target, int* nums, int numsSize){
    
    
    int sum=0;
    int result=INT32_MAX;
    int length=0;
    int i=0,j=0;
    for(i=0;i<numsSize;i++)
    {
    
    
        sum+=nums[i];
        while(sum>=target)
        {
    
    
            length=i-j+1;
            sum-=nums[j];
            j++;
            result=result>length?length:result;
        }
    }
    return result==INT32_MAX?0:result;
}

  滑动窗口可以根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。 每个元素在滑动窗口的进入和出去各操作一次,每个元素被操作两次,时间复杂度为2*n为O(n);

时间复杂度:O(n)
空间复杂度:O(1)

猜你喜欢

转载自blog.csdn.net/Crocodile1006/article/details/131365559