首页 > 其他分享 >长度最小子数组-LeetCode209 滑动窗口

长度最小子数组-LeetCode209 滑动窗口

时间:2022-11-28 10:11:06浏览次数:70  
标签:窗口 nums int 位置 数组 LeetCode209 滑动

力扣:https://leetcode.cn/problems/minimum-size-subarray-sum/

题目

    给定一个含有 n 个正整数的数组和一个正整数 target 。找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [num1, num2, ..., numn-1, numn] ,并返回其长度。如果不存在符合条件的子数组,返回 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

    拿到这道题,我相信大家和我一样,第一时间想到的是暴力解法,两个for循环解决,时间复杂度很明显是O(n^2),暴力解决会超时,这里介绍一个新的方法叫做滑动窗口。

滑动窗口

    所谓滑动窗口,就是不断的调节子序列的起始位置和终止位置,从而得出我们要想的结果。滑动窗口如何用一个for循环来完成这个操作呢。首先要思考 如果用一个for循环,那么应该表示滑动窗口的起始位置,还是终止位置。如果只用一个for循环来表示滑动窗口的起始位置,那么如何遍历剩下的终止位置?此时难免再次陷入暴力解法的怪圈。所以只用一个for循环,那么这个循环的索引,一定是表示滑动窗口的终止位置。那么问题来了, 滑动窗口的起始位置如何移动呢?

    这里还是以题目中的示例来举例,s=7, 数组是 2,3,1,2,4,3,来看一下查找的过程(来自代码随想录):

      

    

    窗口就是 满足其和 ≥ s 的长度最小的连续子数组。窗口的起始位置如何移动:如果当前窗口的值大于s了,窗口就要向前移动了(也就是该缩小了)。窗口的结束位置如何移动:窗口的结束位置就是遍历数组的指针,也就是for循环里的索引。

    解题的关键在于 窗口的起始位置如何移动,如图所示:

        

 

    滑动窗口的精妙之处在于根据当前子序列和大小的情况,不断调节子序列的起始位置。从而将O(n^2)暴力解法降为O(n)。

    代码如下:

class Solution {
    // 滑动窗口
    public int minSubArrayLen(int s, int[] nums) {
        int left = 0;
        int sum = 0;
        int result = Integer.MAX_VALUE;
        for (int right = 0; right < nums.length; right++) {
            sum += nums[right];
            while (sum >= s) {
                result = Math.min(result, right - left + 1);
                sum -= nums[left++];
            }
        }
        return result == Integer.MAX_VALUE ? 0 : result;
    }
}

    其实该题可以看做双指针类似的解法,首先定一个left变量,从第一个元素开始循环1,不断的累加,一旦累加值达到了target,这个时候我们就应该求解最短的子数组和,同时累加值要减去最开始的值,再把left向左移动。

    怎么样,很简单吧,秒,实在是!!!重要在于思路,后面还有该题升级版,难度大了很多,但还是滑动窗口的思想。

标签:窗口,nums,int,位置,数组,LeetCode209,滑动
From: https://www.cnblogs.com/lzdream/p/16927619.html

相关文章

  • Java数组排序
       今天,巩固教大家数组排序方法,我将介绍以下这几种方式:快速排序,冒泡排序,选择排序。1、快速排序这就是各位学Java的福利了,Java提供sort()方法,咱们只......
  • Scala列表数组学习
    数组 不可变数组——定义、查询、增加、循环//定义数据vararr:Array[Int]=newArray[Int](5)vararr2=Array(2,3,42,21,3)//循环以及......
  • 数组
    数据中的元素可以是任意类型数组越界:Index10outofbounds数组是相同类型数据的有序集合,每一个数据成为数组的一个元素,我们可以通过数组的下标(从0开始)来访问它们。定......
  • 1752. 检查数组是否经排序和轮转得到
    1752.检查数组是否经排序和轮转得到classSolution{publicbooleancheck(int[]nums){intn=nums.length;intx=0;for(inti=......
  • WeetCode2滑动窗口系列
    系列文章目录和关于我一丶[无重复字符的最长子串](3.无重复字符的最长子串-力扣(Leetcode))思路:维护一个窗口,窗口中不存在重复的字符,窗口右边界从第一个字符移动到最......
  • VS, VSCode写C/C++代码时, 如何查看二维动态数组的值
    VS(VisualStudio):例:查看第1行的头2列数据,如下图所示 VSCode(VisualStudio):例:查看第1行的头5列数据,第2行的头5列数据,如下图所示......
  • TCP三次握手和四次挥手?TCP如何保证可靠性?什么是TCP滑动窗口?
    TCP三次握手和四次挥手?三次握手tcp3handshake.giftcp3handshake2.giftcp3handshake3.giftcp3handshake4.gif四次挥手tcp4fi......
  • 力扣 leetcode 1752. 检查数组是否经排序和轮转得到
    问题描述给你一个数组nums。nums的源数组中,所有元素与nums相同,但按非递减顺序排列。如果nums能够由源数组轮转若干位置(包括0个位置)得到,则返回true;否则,返回fa......
  • 1752. 检查数组是否经排序和轮转得到 ----- 数组环
    给你一个数组nums。nums的源数组中,所有元素与nums相同,但按非递减顺序排列。如果 nums能够由源数组轮转若干位置(包括0个位置)得到,则返回true;否则,返回false。......
  • ClickHouse 截取数组的部分元素,得到一个新的子数组: arraySlice (array, offset[, leng
    截取数组的部分元素,得到一个新的子数组arraySlice(array,offset[,length])参数解释:array:数组,offset–数组的偏移。正值表示左侧的偏移量,负值表示右侧的缩进值。数组下......