LeetCode 长度最小的子数组

给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。

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

示例 2:
输入:target = 4, nums = [1,4,4]
输出:1

示例 3:
输入:target = 11, nums = [1,1,1,1,1,1,1,1]
输出:0

提示:

1 <= target <= 109
1 <= nums.length <= 105
1 <= nums[i] <= 105

进阶:

如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum

方法一:利用双指针
1、定义两个指针i,j,其中i用于遍历数组,从而计算对应的子数组的和,j用于当和大于等于target的时候后移。此时两个指针的初始值都是0
2、定于一个变量sum,用于统计子数组的和。初始值为0
3、遍历数组,每遍历到一个数字,就将这个数字添加到sum中,然后判断sum是否大于等于了target,如果是,那么就将sum -= nums[ j ] ,然后 j 指针后移。但是我们需要统计子数组中长度最小的,所以在执行sum -= nums[ j ]之前,我们需要先获取 i - j + 1的最小值,将最小值赋值给res
4、遍历完毕之后,res就是我们想要的结果.
对应的代码:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
         int i,sum = 0,j = 0;
         int res = 0,min = Integer.MAX_VALUE;
         for(i = 0; i < nums.length; i++){
         /*
         必须先写sum += nums[i],然后才写while循环,如果将这一步写在while
         循环后面就会导致错误。为什么呢?因为如果将sum += nums[i]这一步写 
         在while循环后面,那么导致sum += nums[nums.length - 1]的时候,sum
         有可能大于等于target,从而没有将所有的情况统计完毕,进而导致错
         误。比如例子[2,3,1,2,4,3],target = 7的时候,那么根据代码进行调
         试的时候就会发现,如果将sum += nums[i]写在while后面,就会错误,
         原因就是上面说的,遍历到最后一个元素的时候,虽然sum += 
         nums[nums.length - 1],但是少算了情况,导致结果的错误.
         */
             sum += nums[i]; 
             while(sum >= target){
             /*
             下面的代码可以写成这样:
             res = Math.min(i - k + 1,res);
             此时只要将res初始化为Integer.MAX_VALUE即可,但是
             这样的话会有一中情况,就是最后返回res的时候我们需要
             判断是否存在大于等于target的子数组,如果不存在,那么就
             返回0,否则返回res,此时我们就需要通过判断res是否等于
             Integer.MAX_VALUE来判断是否存在子数组,所以为了减少
             判断这一步,就使用了下面的代码.
             */
                res = Math.min(i - k + 1,min);
                /*
                这一步是必须的,如果不更新的话,那么min一直都是
                Integer.MAX_VALUE,从而导致res的结果错误。
                */
                min = res;
                sum -= nums[k++];
             }
             
         }
         /*
         如果上面使用的是res = Math.min(i - k + 1,res)的话,那么这时候
         res的初始值是Integer.MAX_VALUE,而不是0,同样的最后不是直接返回
         res,而是判断res是否等于它的初始值,从而可以知道是否存在子数组
         if(res != Integer.MAX_VALUE)
            return res;
         return 0;
         */
         return res;
    }
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值