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

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

示例3

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

题解

法1:暴力法

暴力法很简单,大部分人几乎都能想到。通过两个for循环不断找出满足符合条件的子序列。这样时间复杂度为 O ( n 2 ) O(n^2) O(n2)。由于这种方法过于简单,就不在赘述。下面主要讲指双针法(也称之为滑动窗口法)。

法2:双指针法

双指针法就是通过两个指针来指示一个序列,本题中就是求和的序列。原理很简单:

  • initial:起初两指针均为起点
  • step1:移动右指针使两个指针范围内和大于target。
  • step2:因为这个区间内和大于目标值,因此我们可以缩小该区间,即又移左指针。当区间内值小于target就需停止移动
  • 不断重复step1和step2,直到右指针遍历完数组。

上述过程可能有点抽象,因此画图来具体说明,以示例1为例子。

开始

初始两指针均指向数组0号位置。
在这里插入图片描述

upPtr移动

upPtr移动,使得两指针范围内和大于target(7)。可以看到此时两区间范围内为数字和为8,此时停止移动。
在这里插入图片描述

lowPtr移动

lowPtr移动,从而缩小整个区间。移动后值缩小了
在这里插入图片描述

upPtr移动

在这里插入图片描述

lowPtr移动

在这里插入图片描述

lowPtr移动

在这里插入图片描述

upPtr移动

在这里插入图片描述

lowPtr移动

在这里插入图片描述

lowPtr移动

在这里插入图片描述

upPtr移动–执行完毕

在这里插入图片描述
上述流程对应下面的代码。java版代码如下

 public static int minSubArrayLen(int target, int[] nums) {
        /**
         *@Description:双指针做法,两根指针范围区间即是求和区间
         */
        int sum = 0;
        int lowPtr = 0;
        int shortestLen = nums.length+1;//这是一个取不到的值
        for (int upPtr = 0; upPtr < nums.length; upPtr++) {
            sum += nums[upPtr];//右指针不断移动
            while (sum>=target){//和大了,可以缩小区间了
                shortestLen = Math.min(shortestLen,upPtr-lowPtr+1);
                sum -= nums[lowPtr++];//缩小区间
            }
        }
        return shortestLen == nums.length+1 ? 0:shortestLen;
    }

上述代码注意事项
  • shortestLen 初始化值这里设置的数组长度+1,因为这是一个在例子中取不到的最大值,当然也可以用maxvalue。
  • 结果返回时需要注意特殊情况,即数组内所有元素和相加仍小于target
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值