首页 > 其他分享 >数组——2.长度最小的子数组

数组——2.长度最小的子数组

时间:2024-07-17 18:54:38浏览次数:12  
标签:窗口 cur min 最小 len 数组 滑动 长度

力扣题目链接

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

示例:

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

输入:s = 4,nums = [1,4,4]
输出:1

完整思路如代码随想录所示

本章仅对其中的滑动窗口方法进行解释。

什么是滑动窗口呢?我的理解就是建立一个可以滑动的窗口,具体在于窗口的左右边界是可以移动的,窗口的大小也是不固定的。拿示例中s=7的情况进行举例。

整个数组用图表现是这样的。

首先滑动窗口的左边界停留在数组最左边不动,滑动窗口的右边界开始一格一格的向右移动,直到滑动窗口左右边界内的值之和≥ s,即≥ 7。

在这种情况下,滑动窗口内的值的和等于8大于了s,这时候就需要将滑动窗口的左边界向右移动(一格一格移动)。

移动后将滑动窗口内的和与s进行比较,如果和还是≥ s,那继续移动滑动窗口的左边界;如果和<s,那移动滑动窗口的右边界。

重复上述步骤,直到滑动窗口的右边界到达数组最后,在此过程中其实能得到所有和≥s的情况,从而得到题目要求的最小子数组。具体的关键代码分析如下:

l = len(nums)
left = 0
right = 0
min_len = float('inf')
cur_sum = 0 #当前的累加值

其中min_len = float('inf')的意义在于设定一个初始的最小值以供和后续每个和≥s的滑动窗口长度进行比较。其中float('inf')代表正无穷(ps:float('-inf')代表负无穷,其他题目中如需要比较最大值,可将负无穷作为比较的初始值)。cur_sum代表滑动窗口内值的和。

        while right < l:
            cur_sum += nums[right]
            
            while cur_sum >= s: # 当前累加值大于目标值
                min_len = min(min_len, right - left + 1)
                cur_sum -= nums[left]
                left += 1
            
            right += 1

前两行代码的意思即上文中提到的“滑动窗口的右边界开始一格一格的向右移动”,不停的加入新的值,更新得到的和。

当滑动窗口内的和cur_sum≥s时,代表发现了一个子数组和≥s的情况,将该子数组长度于之前的min_len进行对比,将更小的值赋给min_len。

对比结束后,滑动窗口左边界向右移动一格,同时cur_sum中减去该格的值。如果cur_sum依旧≥s,则继续进行循环while cur_sum >= s:;如果不是,则回到循环while right < l:,同时滑动窗口的右边界再向右移动一格,继续循环,不停的更新min_len,直到所有循环结束。

        return min_len if min_len != float('inf') else 0

理论上,如果存在和≥s的子数组的话,在不停的更新min_len后会得到最小的子数组长度,但还需要考虑滑动窗口右边界一直向右移动直到移动到最后,其和都小于s的情况,该情况下min_len并未进行更新,依旧是正无穷float('inf'),因此在最后的return中还需设置一个if判断,上述代码只是将该判断进行了简化。

标签:窗口,cur,min,最小,len,数组,滑动,长度
From: https://blog.csdn.net/plutomty/article/details/140502388

相关文章

  • 常用的 JavaScript 数组处理方法
    1.map方法用于创建一个新数组,其结果是该数组中的每个元素调用一个提供的函数后返回的结果。letitems=[{id:1,name:'item1'},{id:2,name:'item2'},{id:3,name:'item3'}];letitemNames=items.map(item=>item.name);console.log(itemNames);......
  • NC275631 嘤嘤不想求异或喵,NC274492 76与61,NC273546 小红的数组移动
    目录NC275631嘤嘤不想求异或喵题目描述运行代码代码思路ff 函数解释:主函数解释:NC27449276与61题目描述运行代码代码思路函数 countSubsequences 的工作原理:举例说明:NC273546小红的数组移动题目描述运行代码代码思路嘤嘤不想求异或喵题目描述登录—专......
  • 2024-07-17:用go语言,给定一个整数数组nums, 我们可以重复执行以下操作: 选择数组中的前两
    2024-07-17:用go语言,给定一个整数数组nums,我们可以重复执行以下操作:选择数组中的前两个元素并删除它们,每次操作得到的分数是被删除元素的和。在保持所有操作的分数相同的前提下,请计算最多能执行多少次操作。返回可以进行的最大操作次数。输入:nums=[3,2,1,4,5]。输出:2。......
  • Java开发手册中为什么要求集合转数组toArray时禁止使用无参方法,而使用传参长度为0的空
    场景Java中使用JMH(JavaMicrobenchmarkHarness微基准测试框架)进行性能测试和优化:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/131723751参考以上性能测试工具的使用。阿里巴巴《java开发手册》泰山版关于集合转数组时规范声明:【强制】使⽤集合转数组的⽅......
  • 数组是缓存对齐的特征
    Anarrayiscache-aligned:Thesizeofeacharrayelementmatchesthesizeofthecacheblock.Thestartingaddressofthearrayisamultipleofthecacheblocksize.Let'selaborateonthesepoints:ArrayElementSizeMatchesCacheBlockSizeI......
  • java的数组
    程序=逻辑+数据,数组是存储数据的强而有力的手段。——闫学灿一维数组数组的定义//int[]a;//定义//a=newint[10];//初始化int[]a=newint[10],b;//边定义边初始化,b也是数组,但是没有初始化,是一个空数组float[]f=newfloa......
  • 力扣刷题笔记-删除数组中的重复元素
    纠结要不要离开杭州删除数组中的重复元素思想双指针/快慢指针只有当两个元素不相等的时候才发生复制和p指针向后移动如果两个指针指向的元素相等,则q指针向后移动p和q不相邻的情况下才发生复制和替换,如果相邻,只是简单的q指针向后移动p指针是慢指针,q指针是快指针,当p和q指向......
  • 找到两个数组中的公共元素
    leetcode2956https://leetcode.cn/problems/find-common-elements-between-two-arrays/一次遍历实现classSolution:deffindIntersectionValues(self,nums1:List[int],nums2:List[int])->List[int]:arr=[0]*110forninnums1:......
  • 2956. 找到两个数组中的公共元素
    思路:用两个map分别存储两个列表内容,然后再对照即可classSolution{public:vector<int>findIntersectionValues(vector<int>&nums1,vector<int>&nums2){unordered_map<int,int>mp1;unordered_map<int,int>mp2;......
  • 【c语言】函数递归的一些例题1.编写一个函数,不许创建临时变量,求字符串长度 2.求n的阶
    1.intmy_strlen(char*str){   if(*str!='\0')   {      return1+my_strlen(str+1);//利用递归求字符串长度:递归一次就是多一个字符这样就可以求出字符串的长度了   }   else      return0;}intmain(){   //编写......