力扣每日一题-长度最小的子数组

题目描述

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/minimum-size-subarray-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路分析

暴力法

假设子序列长度为无限大;
两个for循环
第一层循环 遍历数组中每个元素,作为起始位置,寻找结束位置
第二层循环 从起始位置开始,寻找结束位置
当结果>=s时,结果赋值
否则 继续寻找;

双指针法—滑动窗口

两个指针slow,quick。
quick依次向后,相加为子区间的和。当和大于s时,需要子区间减小,即slow++;这是sum需要-= nums[slow];
当和小于时,quick++即可,直至quick到达数组末尾

滑动窗口:不断调节子序列的起始位置和终止位置,从而得出想要的结果

  • 窗口内是什么 – 子序列 【满足其和 >= s 的长度最小的 连续的子数组】
  • 起始位置的确定:当前窗口>s 窗口向前移动
  • 结束位置的确定:遍历数组的指针

代码:

class Solution {
    public int minSubArrayLen(int s, int[] nums) {

        // //暴力法   时间复杂度O(n^2)
        // int n=nums.length;
        // if( n == 0){
        //     return 0;
        // }
        // int result = Integer.MAX_VALUE;
        
        // for(int i = 0; i < n ;i++){
        //    int sum=0; 
        //     for(int j = i;j < n; j++){
        //         sum += nums[j]; 
        //         if(sum >= s){
        //             result = Math.min(result, j-i+1);
        //             break;
        //         }     
        //     }  

        // }
        // return result == Integer.MAX_VALUE ? 0 : result;


        //双指针 时间复杂度:O(n) 空间复杂度O(1)
        int n=nums.length;
        // if(n == 0) {
        //     return 0;
        // }
        int slow = 0,quick = 0;
        int result = Integer.MAX_VALUE;
        int sum = 0;
        while(quick < n) {
            sum += nums[quick];
            while(sum >= s) {
                result=Math.min(result,quick-slow+1);
                sum -= nums[slow];
                slow++;
            }
            quick++;
        }
        return result == Integer.MAX_VALUE ? 0:result;

    }
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 设计师:Kelly-Li 返回首页