LeetCode刷题---209. 长度最小的子数组(双指针-滑动窗口)

简介: LeetCode刷题---209. 长度最小的子数组(双指针-滑动窗口)



一、编程题:209. 长度最小的子数组(双指针-滑动窗口)

1.题目描述

  给定一个含有 n 个正整数的数组和一个正整数 target 。

  找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。 LeetCode题目链接。

2.示例1:

输入:target = 7, nums = [2,3,1,2,4,3]

输出:2

解释:子数组 [4,3] 是该条件下的长度最小的子数组。

3.示例2:

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

输出:1

4.示例3:

输入:target = 11, nums = [1,1,1,1,1,1,1,1]

输出:0

5.提示:

  • 1 <= target <= 109
  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 105

6.进阶:

  • 如果你已经实现 O(n) 时间复杂度的解法, 请尝试设计一个 O(n log(n)) 时间复杂度的解法。

二、解题思路

这次还是老规矩练习一下双指针的思想,不枉练习这么多次双指针的题,现在双指针思路算是有一点长进了。其关键点还是该怎么去移动这两个指针?这一点要理清楚。;

1.思路

解决方法1(个人想法):

  • Step 1.创建left,right分别指向滑动窗口的开始位置和结束位置,并用min存储数组中得到的最小长度和维护变量sum存储滑动窗口中的元素和(即nums[left]到nums[right]);
  • Step 2.通过循环移动窗口的右指针right,当sum>=target时,记录当前滑动窗口长度,然后将left尝试向右边移动,直到sum<target为止,这样就能得到滑动窗口中最小长度;
  • Step 3.重复Step2步直到right>target遍历结束,就能得到子数组的最小长度了;

一开始就是用滑动窗口进行移动寻找子数组,但对循环的结束判定却把握不准,导致程序运行超时。

2.复杂度分析:

时间复杂度 O(N): 其中N是数组的长度。指针left和right最多各移动N次。

空间复杂度 O(1): 使用常数额外空间。

3.算法图解

红色部分代表滑动窗口的大小。(注:本人不会做成流程动画,希望会的朋友可以私信我指点一二,说个软件名字也可以,谢谢


三、代码实现

。每个代码块都写了注释,方便理解,代码还可以改进;

代码如下(示例):

解法一:

class Solution {
    public int minSubArrayLen(int target, int[] nums) {
        //方法一
        //初始状态下,left和right都指向下标0,sum的值为0。
        int left = 0, right = 0, length = nums.length-1, min = length+2, sum = 0;
        while(right <= length){
            sum += nums[right];
            //当滑动窗口内总数之和大于或等于目标值时,则left试着向右边移动,寻找最小长度
            while(sum >= target){
                min = Math.min(min, right-left+1);
                sum -= nums[left++];
            }
            right++;
        }
        return min == length+2 ? 0 : min;
        //错误思路
        <!-- if(sum < target){
            right++;
            if(right > length && min == length + 2) return 0;
        } 
        else{
            while(sum >= target){
                sum -= nums[left++];
            }
            min = Math.min(min, right-left+2);
            sum = 0; 
            
            left++;
            right = left;
        }
        return min == length+2 ? 0 : min; -->
    }
}

提交结果:


总结

以上就是今天要讲的内容,做题的时候,就是奔着双指针的思路进行解决的,练习这么多次现在逐渐找到了点感觉。我感觉就是双指针的关键点就是在于该怎么去移动两个指针,理清这一点之后离结果也就不远了,这次双指针都是指向滑动窗口来进行移动才能减少运行时间,但想好了怎么移动这两个指针,却卡着不知道该怎么结束循环,这块没想好导致程序运行最后一个例子时报运行超时。所以就赶紧记录一下这时刻。

感谢观看,如果有帮助到你,请给题解点个赞和收藏,让更多的人看到。🌹 🌹 🌹

也欢迎你,关注我。👍 👍 👍

原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!


相关文章
【LeetCode 26】239.滑动窗口最大值
【LeetCode 26】239.滑动窗口最大值
237 1
|
算法 容器
【算法】——双指针算法合集(力扣)
移动零,复写零,快乐数,盛最多水的容器,有效三角形的个数,和为s的两个数(查找总价格为目标值的两个商品 ),三数之和,四数之和
|
算法 Python
【Leetcode刷题Python】子数组查找
一个用于寻找给定字符串中最长重复子串的Python函数实现,采用了滑动窗口的方法来检测重复的子串。
168 1
|
Python
【Leetcode刷题Python】138. 复制带随机指针的链表
LeetCode上题目“138. 复制带随机指针的链表”的Python解决方案,包括两种方法:一种是在每个节点后复制一个新节点然后再分离出来形成新链表;另一种是构建一个字典来跟踪原始节点与其副本之间的映射关系,从而处理新链表的构建。
293 1
【LeetCode 04】滑动窗口法总结
【LeetCode 04】滑动窗口法总结
242 0
|
算法 Java
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
LeetCode初级算法题:子数组最大平均数+二叉树的最小深度+最长连续递增序列+柠檬水找零
331 0
|
存储 Python
【Leetcode刷题Python】239. 滑动窗口最大值
文章介绍了两种解决LeetCode上"滑动窗口最大值"问题的方法:使用大堆树和双向递减队列,提供了详细的解析和Python代码实现。
446 0
|
存储 算法
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
295 0
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
2194 13
|
存储 人工智能 C语言
C语言程序设计核心详解 第八章 指针超详细讲解_指针变量_二维数组指针_指向字符串指针
本文详细讲解了C语言中的指针,包括指针变量的定义与引用、指向数组及字符串的指针变量等。首先介绍了指针变量的基本概念和定义格式,随后通过多个示例展示了如何使用指针变量来操作普通变量、数组和字符串。文章还深入探讨了指向函数的指针变量以及指针数组的概念,并解释了空指针的意义和使用场景。通过丰富的代码示例和图形化展示,帮助读者更好地理解和掌握C语言中的指针知识。
1002 4