leetcode长度最小的子数组

给定一个含有 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组如果不存在符合条件的连续子数组,返回 0。

示例: 

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

进阶:

如果你已经完成了O(n) 时间复杂度的解法, 请尝试 O(n log n) 时间复杂度的解法。

方法一:蛮力法

int solve(int a[],int n,int s)
{//暴力破解法,枚举所有子数组
    int i,j,sum;
    int minlen = n+1;
    for(i=0;i<n;i++)
    {
        sum=0;
        for(int j=i;j<n;j++)
        {
            sum+=a[j];
            if(sum>=s)
            {
                minlen = minlen>(j-i+1)?(j-i+1):minlen;
            }
        }
    }
    if(minlen==n+1)
        return 0;
    return minlen;
}

方法二:指针对撞法,设置快慢指针

  要求是连续子数组,所以我们必须定义 i,j两个指针,i 向前遍历,j 向后遍历,相当与一个滑块,这样所有的子数组都会在 [i...j] 中出现,如果 nums[i..j] 的和小于目标值 s,那么j向后移一位,再次比较,直到大于目标值 s 之后,i 向前移动一位,缩小数组的长度。遍历到i到数组的最末端,就算结束了,如果不存在符合条件的就返回 0。

当sum小于正数s时,快指针向右遍历,加上当前数;sum大于s时,舍去慢指针(左边)所指元素,直到慢指针达到数组右端。

#include<stdio.h>

int solve2(int a[],int n,int s)
{
 int i=0,j=-1;    //滑动窗口 
 int sum=0,minlen=n+1;
 while(i<n)
 {
     if(sum<s&&j<n)
     {
         sum+=a[++j];
    }
    else
    {
        sum-=a[i++];
    }
    if(sum>=s)
        minlen = (j-i+1)<minlen?(j-i+1):minlen;
 }
 return minlen==n+1?0:minlen;
}  

int main()
{
    int a[]={2,3,1,2,4,3},s=7;
    int minlen = solve2(a,6,s);
    printf("%d\n",minlen);
    
    return 0;
} 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值