数组-长度最小的子数组

题目:https://leetcode-cn.com/problems/minimum-size-subarray-sum/

长度最小的子数组

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

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

暴力破解

使用两个 for 循环,一个 for 循环固定一个数字比如 m,另一个 for 循环从 m 的下一个元素开始累加
比较经典的 for (int i = 0; i < nums.length; i++) for (**int j = i **; j < nums.length; j++)
当和大于等于 s 的时候终止内层循环,顺便记录下最小长度。

这里学着用一下人家的标准解来给result赋值
因为,java int 类整数的最大值是 2 的 31 次方 - 1 = 2147483648 - 1 = 2147483647

可以用 Integer.MAX_VALUE 表示它,即 int value = Integer.MAX_VALUE;

public int minSubArrayLen(int target, int[] nums) {
        int size = nums.length;
        int result = Integer.MAX_VALUE;
        for(int i = 0;i<size;i++){
            int sum = 0;
            for(int j =i;j<size;j++){
                sum += nums[j];
                if(sum>=target){
                    //每次都与之前的进行比较,找到最小的子序列
                    result = Math.min(result,j-i+1);//比如1到5,5-1+1
                    break;
                }
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == Integer.MAX_VALUE ? 0 : result;
    }

时间复杂度:O(n^2)其中n是数组的长度。需要遍历每个下标作为子数组的开始下标,对于每个开始下标,需要遍历其后面的下标得到长度最小的子数组。

滑动窗口(双指针的一种)

像之前的数组-移除元素一样,两个指针,一快一慢,快的负责遍历,慢的负责找到记录下符合要求的,不同之处在于移除完元素后,我们直接返回slow,而这里我们需要一直不停的记录长度,并做比较。

  1. 先写出slow不动,fast像i一样开始遍历数组,从0开始加到符合条件,然后记录下长度。
  2. 我们已经测试过,前三个数的和不满足,前四个数的和满足。此时我们移动slow指针,来判断,从第二个数到第四个数的和是否满足(若满足则slow继续后移动,不满足就让fast移动)。这里我们将if的判断,换成while来循环判断slow到fast区间内的和是否满足,并记录下最短长度。

在这里插入图片描述

    public int minSubArrayLen(int target, int[] nums) {
        int size = nums.length;
        int result = Integer.MAX_VALUE;
        int sum = 0;
        int slow = 0;
        for(int fast=0; fast<size; fast++){
            sum+=nums[fast];
            while(sum>=target){
                result = Math.min(result,fast-slow+1);//注意这两行代码的顺序,正如图中所述
                sum-=nums[slow];
                slow++;
            }
        }
        // 如果result没有被赋值的话,就返回0,说明没有符合条件的子序列
        return result == Integer.MAX_VALUE ? 0 : result;
    }

参考:代码随想录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值