当前位置: 首页 > news >正文

【C++算法】10.滑动窗口_长度最小的子数组

文章目录

    • 题目链接:
    • 题目描述:
    • 解法
    • C++ 算法代码:
    • 图解


题目链接:

209. 长度最小的子数组


题目描述:

1170422f911c06f1e598ea59a29ecac5


解法

解法一:暴力求解(会超时)

暴力枚举出所有子数组的和。

查找子数组n2,求和n

一共O(n3)

优化:

求和的时候,可以把上次求和的结果存起来,往后加一位的时候直接把那一位的值加到上次的和里面。

解法二:滑动窗口O(n)

利用单调性,使用同向双指针来优化。(同向双指针也叫滑动窗口)

  1. left=0,right=0,标记窗口的左右端点
  2. 进窗口
  3. 判断,更新结果🌟,出窗口

2-3步是一直循环的

例如:nums=[2,3,1,2,4,3]

bf6f7a41e4c0f24e3385c0f646767131

移动到sum>=target

6534792b2aa1723748d3fa03cddf0bc9

然后left右移,因为如果left不动,right继续往后得到的都不是长度最小的数组了。

aa3c1e36590f6a910fb325c20970fa2b

sum<target,right右移

98dad4dddeee070163985dcba31f6609

依次类推

然后窗口的长度可以用len来记录,每次判断后先更新结果,然后出窗口。


C++ 算法代码:

解法一:暴力求解(会超时)

class Solution {public:int minSubArrayLen(int target, vector<int>& nums) {// 记录结果int ret = INT_MAX;int n = nums.size();// 枚举出所有满足和大于等于 target 的子数组[start, end// 由于是取到最小,因此枚举的过程中要尽量让数组的长度最小// 枚举开始位置for (int start = 0; start < n; start++){int sum = 0; // 记录从这个位置开始的连续数组的和// 寻找结束位置for (int end = start; end < n; end++){sum += nums[end]; // 将当前位置加上if (sum >= target) // 当这段区间内的和满足条件时{// 更新结果,start 开头的最短区间已经找到ret = min(ret, end - start + 1);break;}}}// 返回最后结果return ret == INT_MAX ? 0 : ret;}
};

解法二:

class Solution 
{public:int minSubArrayLen(int target, vector<int>& nums) {int n = nums.size(), sum = 0, len = INT_MAX;for(int left = 0, right = 0; right < n; right++){sum += nums[right]; // 进窗口while(sum >= target) // 判断{len = min(len, right - left + 1); // 更新结果sum -= nums[left++]; // 出窗口}}return len == INT_MAX ? 0 : len;}
};

图解

nums=[2,3,1,2,4,3]

target=7

  1. n=6,sum=0,right=0,left=0,target=7,len=INT_MAX(确保min使用的时候不会把len的初始值当作最小值)

b000e57b75676632dd08955353dcf5f6

  1. sum=2

    sum<target,right++

a26691d21d504806c3bd541f0e84a510

  1. sum=5

    sum<target,right++

88c4dd7832bfdeb9cbaf7889c41dbef0

  1. sum=5

    sum<target,right++

216734ef9302afa8c1e63071380c329f

  1. sum=8

    sum>target,len=4

    sum=sum-nums[left++]=8-2=6

ed97423f50bce4cfa4726e06b66751e7

  1. sum=6

    sum<target,right++

d055ae3daef5ce1fefa302efca207622

  1. sum=10

    sum>target,len=4

    sum=sum-nums[left++]=10-3=7

d80a4ad69c27c089f1261afef6455762

  1. sum=7

    sum=target,len=3

    sum=sum-nums[left++]=7-1=6

973a3fe82a527723d2848853fb0f99cb

  1. sum=6

    sum<target,right++

5b759f03d0c01c3cc4abdd5a1c2a8892

  1. sum=9

    sum>target,len=3

    sum=sum-nums[left++]=9-2=7

328afb03c2ae215109c04c4becc5ddbe

  1. sum=7

    sum=target,len=2

    sum=sum-nums[left++]=7-4=3

bd5301b2ad254ec8435695ecc4437004

  1. sum=3

    sum<target,right++

cc49d00b9fff8a978d8ef4972098214c

  1. 跳出for循环,return len == INT_MAX ? 0 : len;,这里返回2

  2. 程序结束


http://www.mrgr.cn/news/42748.html

相关文章:

  • 【移动端】Viewport 视口
  • node配置swagger
  • python 实现Luhn (Mod 10)Algorithm算法
  • D27【 python 接口自动化学习】- python 基础之判断与循环
  • 基于深度学习的从自然语言生成代码
  • 《深度学习》OpenCV 图像拼接 原理、参数解析、案例实现
  • SSL 协议(HTTPS 协议的关键)
  • 微服务之间的相互调用的几种常见实现方式对比
  • linux命令学习
  • 【移动端】基础知识
  • C文件操作
  • 快速选择 vs 最小堆:如何在数组中高效找到第K大元素?
  • C(十一)scanf、getchar(第三弹)
  • python全栈学习记录(二十二)多态性、封装、绑定方法与非绑定方法
  • 从0到1:培训机构排课小程序开发笔记一
  • 17 链表——21. 合并两个有序链表 ★
  • 深度学习每周学习总结J1(ResNet-50算法实战与解析 - 鸟类识别)
  • C语言 动态数据结构的C语言实现内存映像
  • 2024年PCDN业务严峻?家里网络不好可能是因为它
  • Flink 03 | 数据流基本操作