Minimum Size Subarray Sum

本文探讨了如何找到一个正整数数组中,满足总和大于等于给定目标值的最小子数组长度的问题。提供了两种解决方案:一种是使用回溯算法求解所有可能的子数组(非连续),另一种则是通过双指针法高效地寻找符合条件的最短连续子数组。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:
Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn’t one, return 0 instead.

For example, given the array [2,3,1,2,4,3] and s = 7,
the subarray [4,3] has the minimal length under the problem constraint.

这个题一开始没怎么弄清题意,写了一个回溯算法求子数组,但是我求出来的并不是连续子数组,可以参考一下:

public int minSubArrayLen(int s, int[] nums) {
    int minLen=Integer.MAX_VALUE,sum=0,start=0,len=0;
    List<Integer> list=new ArrayList<Integer>();
    trace(list, s, nums, sum, len, start);
    for (int i = 0; i < list.size(); i++) 
        minLen=minLen<list.get(i)?minLen:list.get(i);
    return minLen;
}

public void trace(List<Integer> list,int s,int[] nums,int sum,int len,int start){
    if(sum==s){
        list.add(len);
        return;
    }
    if(sum>s)
        return;
    for(int i=start;i<nums.length;i++){
        trace(list, s, nums, sum+nums[i], len+1, i+1);
    }
}

后来看到连续子数组之后,我的第一反应就是二分法,于是就想到了Maximum Subarray这一题。但是这个题用那个思路解不出来。换个思路就想到了两个指针的办法,代码如下所示:

public int minSubArrayLen(int s, int[] nums) {
    int left=0,right=0;
    int len=0,minLen=Integer.MAX_VALUE,n=nums.length;
    if(n==0)
        return 0;
    int sum=nums[0];
    while(right<n){
        //先比较,再移动
        if(sum>=s){
            len=right-left+1;
            minLen=len<minLen?len:minLen;
        }
        if(sum<=s||left==right){
            right++;
            if(right==n)
                break;
            sum+=nums[right];

        }else{
            sum-=nums[left++];
        }
    }
    //下面这一部分不需要,因为当right==n-1的时候left已经在往右走,当right==n直接结束
    /*while(sum>=s){
        minLen=len<minLen?len:minLen;
        len--;
        sum-=nums[left++];
    }*/                      
    return minLen==Integer.MAX_VALUE?0:minLen;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值