每天一题 LeetCode 209 最小子数组

 最小子数组:

给定一个含有 n 个正整数的数组和一个正整数 target 。

找出该数组中满足其总和大于等于 target 的长度最小的 子数组

 [numsl, numsl+1, ..., numsr-1, numsr] ,并返回其长度如果不存在符合条件的子数组,返回 0 。

示例 1:

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

 解析:滑动窗口解法

既然叫滑动窗口就得有一个在逻辑上像是窗口的边界的东西,我们定义的这个窗口应该是从左至右进行遍历的

如图,我现在创建了一个窗口将2这个元素包含进去了,此时窗口中元素的值和为2 ,假设target这个目标值为7,此时窗口中的元素和是小于7的,那么我们需要不断的扩大窗口使窗口中的元素和是大于等于7的。

想要在这个数组中找到一个最小的子数组和能大于7的,我们就得先找到一个和能大于7的子数组

此时我们找到了第一个大于等于7的子数组,先将这个结果记录下来,方便之后找到第二个结果时进行比较。此时我们知道窗口中的元素和是大于等于7的但不知道是不是最短的, 所以此时缩小窗口的大小将第一个元素移除,因为我们已经将这个结果记录下来了所以可以移除,此时我们窗口元素和再次小于了7,继续循环上次的操作,直至窗口的右边界到达数组的右端。

  

经过循环我们已经遍历了所有子数组和能大于等于7的子数组并将它们的长度进行比较,最后得到结果。

下列是c语言实现代码

#define INT_MAX 2147483647
int minSubArrayLen(int target, int* nums, int numsSize) { 
    int left=0;                                //定义左指针为数组起始位置
    int sum = 0;                               //定义用于与target比较的变量
    int result =INT_MAX;
    for(int right=0;right<numsSize;right++){   //用窗口的右边界遍历数组
        sum+=nums[right];                      //将当前的元素添加到当前子数组的和中
        while(sum>=target){                    //当当前子数组的和大于等于 target 时,尝试缩小子数组的长度
            int length = right-left+1;          
            if(result>length){
                result = length;               //记录当前数组长度
            }
            sum-=nums[left++];                 //缩小子数组的长度,左指针右移,并从和中减去左指针指向的元素    
        }
    }
    // 如果 result 仍然是 INT_MAX,说明没有找到符合条件的子数组,返回0;否则返回找到的最短子数组的长度
    return result == INT_MAX ? 0 : result;
}

以下是c语言完整代码:

#include<stdio.h>
#define INT_MAX 2147483647
int minSubArrayLen(int target, int* nums, int numsSize) { 
    int left=0;                                //定义左指针为数组起始位置
    int sum = 0;                               //定义用于与target比较的变量
    int result =INT_MAX;
    for(int right=0;right<numsSize;right++){   //用窗口的右边界遍历数组
        sum+=nums[right];                      //将当前的元素添加到当前子数组的和中
        while(sum>=target){                    //当当前子数组的和大于等于 target 时,尝试缩小子数组的长度
            int length = right-left+1;          
            if(result>length){
                result = length;               //记录当前数组长度
            }
            sum-=nums[left++];                 //缩小子数组的长度,左指针右移,并从和中减去左指针指向的元素    
        }
    }
    // 如果 result 仍然是 INT_MAX,说明没有找到符合条件的子数组,返回0;否则返回找到的最短子数组的长度
    return result == INT_MAX ? 0 : result;
}
int main(){
    int n,target;
    printf("输入数组长度:");
    scanf("%d",&n);
    printf("输入target:");
    scanf("%d",&target);
    int arr[n];
    for(int i=0;i<n;i++){
        scanf("%d",&arr[i]);
    }
    int result = minSubArrayLen(target,arr,n);
    printf("result: %d",result);
    return 0;
}

下列是示例:

感谢你看到这里如果代码有误或无法运行请留言 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值