代码随想录day2-长度最小的子数组

178 阅读1分钟

题目介绍

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

题目解读

题目的简单介绍就是在一个连续且无序的数组中找到一个子序列总和大于目标值,返回使用需要使用的子序列总和所使用到的元素数量最小。如果没有正确答案情况下,直接返回0。

解题想法

1. 双for暴力解 想法很简单,以当前元素为基点不停累加直至加到大于或等于目标值时候跳出循环,记录此次所使用元素个数。代码如下

     public int minSubArrayLen(int target, int[] nums) {
        int res = 10001;
        for(int i = 0;i < nums.length; i++ ){
            int sum = 0;
            for(int j = i ; j < nums.length; j++){
                sum+=nums[j];
                if(sum >= target){
                    res = Math.min(res,j - i + 1 );
                    break;
                }
            }
        }
        if(res == 10001)return 0;
        return res;
    }

亲测,这段代码会超过时间限制,时间复杂度为O(n^2),空间复杂度为常量。 2.双指针解法想法:想象现在有一个队列,我们不停地向队列空间增加元素,直至元素累加到超过目标值。然后不断从头拿元素,不够元素就增加,始终维持在累加值在目标值之上。下面是代码实现

public static int minSubArrayLen(int target, int[] nums) {
    int slow = 0;
    int sum = 0;
    int min = Integer.MAX_VALUE;
    for (int fast = 0; fast < nums.length; fast++) {
        sum += nums[fast];
        while (sum >= target) {
            min = Math.min(fast - slow + 1, min);
            sum -= nums[slow++];
        }
    }
    return min;
}