leetcode 滑动窗口小结 (一)

目录

  • 小结以及代码框架
  • 76. 最小覆盖子串
    • 滑动窗口
    • 代码以及注释
  • 567. 字符串的排列
    • 滑动窗口
  • 438. 找到字符串中所有字母异位词
  • 3. 无重复字符的最长子串
    • 化简框架
  • reference

小结以及代码框架

滑动窗口技巧属于双指针技巧。
该算法的思路为维护一个窗口,不断滑动,然后更新答案。
大致框架如下:[参考labuladong的算法小抄]

int left = 0, right = 0;while(right < s.size())
{//增大窗口window.add(s[right]);right++;while(window needs shrink){//缩小窗口window.remove(s[left]);left++;}
}

主要的细节问题:
1、如何向窗口中添加新元素
2、如何缩小窗口
3、在窗口滑动的哪个阶段更新结果

//滑动窗口算法框架
void slidingWindow(string s, string t)
{unordered_map<char,int> need, window;for(char c : t) need[c]++;int left = 0, right = 0;int valid = 0;while(right < s.size()){//c是将要移入窗口的元素char c  = s[right];//右移窗口right++;//进行窗口内数据更新(右移窗口)/*******************//**debug输出位置***/cout << "window:[ "<<left << " , " << right <<"]"<<endl;/******************///判断左侧窗口是否需要收缩while(window needs shrink){//d是将移出窗口的字符char d = s[left];//左移窗口left++;//进行窗口内数据的一系列更新(左移窗口)}}
}

76. 最小覆盖子串

https://leetcode-cn.com/problems/minimum-window-substring/
给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

注意:如果 s 中存在这样的子串,我们保证它是唯一的答案。
示例 1:

输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”

示例 2:

输入:s = “a”, t = “a”
输出:“a”

提示:
1 <= s.length, t.length <= 10^5
s 和 t 由英文字母组成

滑动窗口

1、初始化window和need两个哈希表,记录下窗口中的字符以及需要凑齐的字符:

unordered_map<char,int> need,window;
for(char c : t) need[c]++;

2、使用left和right变量初始化窗口两端,区间是左闭右开,初始情况下,窗口内是没有元素的。

int left = 0, right = 0;
while(right < s.size())
{//开始滑动
}

3、定义记录变量
valid_length表示window内满足need条件的字符个数,如果valid_length == need.size() 说明窗口已经满足了条件,已经完全覆盖了串T。

int valid_length;

在right向右扩充的时候,对新进来的元素进行检查,如果它是need中的元素,window中对应这个元素就要+1,然后判断window中这个元素的个数是不是need中这个元素的个数相同,如果相同说明这个元素在window中已经找完了,这时候就需要将valid_length+1了
4、套用模板
确定四个问题的具体细节:
1、当right移动,扩大window,应该更新哪些数据?

更新window计数器

2、当left移动,缩小window,应该更新哪些数据?

更新window计数器

3、什么条件下暂停扩大window,开始移动left缩小window?

当valid长度等于need大小时,应该收缩窗口

4、结果应该在扩大窗口时还是缩小窗口时进行?

缩小窗口的时候进行更新结果

代码以及注释

class Solution {
public:string minWindow(string s, string t) {unordered_map<char,int> window,need;//记录下t中有哪些元素以及每个元素的个数for(char c : t) need[c]++;//初始化窗口边界int right = 0, left = 0;//window满足need条件的元素个数int valid_length = 0;//结果字符串在s中的起始地址以及长度,这样就不要每次更新整个string了int start = 0 , length = INT_MAX;while(right < s.size()){//******************扩充窗口**************//扩充窗口right++;//扩充进来的新元素char c = s[right - 1]; //判断该元素是否是need中元素if(need.count(c)){window[c]++;if(window[c] == need[c]) valid_length++;}//*******************缩小窗口*************//如果need中所有元素都在window内,并且每个元素的频数也与window内元素频数相同,那么此时就得到了一个答案,记录答案,然后缩小窗口,以获得更优的答案while(valid_length == need.size()){//如果此次答案比上次的答案长度要小,我们才更新答案if(right - left < length){start = left;length = right - left;}//左边界向左移动left++;//d是刚移出窗口的元素char d = s[left - 1];//如果need中出现了dif(need.count(d)){//如果之前d元素在window和need出现的频数相同if(window[d] == need[d]){//删除了之后,频数不相同了,所以这个元素也就不满足了。valid_length--;}window[d]--;}}}//如果length没有更新,说明s不存在t中字符或者不满足字符频数,返回空字符串,否则,使用substr将子串返回return length == INT_MAX ? "" : s.substr(start,length);}
};

567. 字符串的排列

https://leetcode-cn.com/problems/permutation-in-string/
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。

换句话说,第一个字符串的排列之一是第二个字符串的子串。

示例1:

输入: s1 = “ab” s2 = “eidbaooo”
输出: True
解释: s2 包含 s1 的排列之一 (“ba”).

示例2:

输入: s1= “ab” s2 = “eidboaoo”
输出: False

注意:

输入的字符串只包含小写字母
两个字符串的长度都在 [1, 10,000] 之间

滑动窗口

精确化题目为:假设给你一个S和T,请问S中是否存在一个子串,包含T中所有字符且不包含其他字符
精确化本题细节:
1、移动left缩小窗口的时机:窗口大小大于t的大小,因为各种排列的长度应该是一样的。
2、当valid_length == need.size()时,说明窗口中的数据是一个合法的数据,应该立即返回true;

class Solution {
public:bool checkInclusion(string s1, string s2) {unordered_map<char,int> window,need;for(char c : s1) need[c]++;int left = 0,right = 0;int valid_length = 0;while(right < s2.size()){//扩充windowright++;char c = s2[right - 1];if(need.count(c)){window[c]++;if(window[c] == need[c]) valid_length++;}//缩小windowwhile(right - left >= s1.size()){if(valid_length == need.size()) return true;left++;char d = s2[left - 1];if(need.count(d)){if(window[d] == need[d]) valid_length--;window[d]--;}}}return false;}
};

438. 找到字符串中所有字母异位词

https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/
给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。

字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。

说明:
字母异位词指字母相同,但排列不同的字符串。
不考虑答案输出的顺序。
示例 1:

输入:
s: “cbaebabacd” p: “abc”
输出:
[0, 6]
解释:
起始索引等于 0 的子串是 “cba”, 它是 “abc” 的字母异位词。
起始索引等于 6 的子串是 “bac”, 它是 “abc” 的字母异位词。

** 示例 2:**

输入:
s: “abab” p: “ab”
输出:
[0, 1, 2]
解释:
起始索引等于 0 的子串是 “ab”, 它是 “ab” 的字母异位词。
起始索引等于 1 的子串是 “ba”, 它是 “ab” 的字母异位词。
起始索引等于 2 的子串是 “ab”, 它是 “ab” 的字母异位词。

直接套模板

class Solution {
public:vector<int> findAnagrams(string s, string p) {if(s.empty()) return {};vector<int> result;unordered_map<char,int> need,window;for(char c : p) need[c]++;int left = 0,right = 0;int valid_length = 0;while(right < s.size()){//expand windowright++;char c = s[right - 1];if(need.count(c)){window[c]++;if(window[c] == need[c]){valid_length++;}}//shrink windowwhile(right - left >= p.size()){if(valid_length == need.size()){result.emplace_back(left);}left++;char d = s[left - 1];if(need.count(d)){if(window[d] == need[d]){valid_length--;}window[d]--;}}}return result;}
};

3. 无重复字符的最长子串

之前做过,这次用滑动窗口模板做:
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:

输入: s = “abcabcbb”
输出: 3
解释: 因为无重复字符的最长子串是 “abc”,所以其长度为 3。

示例 2:

输入: s = “bbbbb”
输出: 1
解释: 因为无重复字符的最长子串是 “b”,所以其长度为 1。

示例 3:

输入: s = “pwwkew”
输出: 3
解释: 因为无重复字符的最长子串是 “wke”,所以其长度为 3。
请注意,你的答案必须是 子串 的长度,“pwke” 是一个子序列,不是子串。

示例 4:

输入: s = “”
输出: 0

提示:

0 <= s.length <= 5 * 10^4
s 由英文字母、数字、符号和空格组成.

化简框架

将need、valid去除,更新窗口数据只需要更新window计数器。
当window[c]大于1,说明窗口内存在重复字符,不符合条件,就应该移动left缩小窗口。
对于更新结果:更新结果的操作放在收缩窗口之后,因为收缩之后窗口不存在重复字符。

class Solution {
public:int lengthOfLongestSubstring(string s) {if(s.empty()) return 0;int res = 0;unordered_map<char,int> window;int left = 0, right = 0;while(right < s.size()){//expand windowright++;char c = s[right -1];window[c]++;//如果进入窗口的新元素在窗口内有重复元素,就需要移动left//shrink windowwhile(window[c] > 1){left++;window[s[left - 1]]--;}res = max(res,right - left);}return res;}
};

reference

《labuladong的算法小抄》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/377548.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux命令行界面_Linux中的命令行界面

linux命令行界面If you are like most people, you are probably most familiar with using a Graphical User Interface (GUI) to control your computer. Introduced to the masses by Apple on the Macintosh computer and popularized by Microsoft, a GUI provides an eas…

一道小小面试题的细节分析

一道小小面试题的细节分析 今天突然想到以前遇到的一个问题&#xff0c;题目如下&#xff08;可能绝大多数人都遇到过&#xff09;&#xff1a; 1 class A2 {3 public A()4 {5 PrintFields();6 }7 public virtual void Pr…

十四、OPTIM

一、torch.optim torch.optim.Optimizer(params, defaults)优化器官网说明 由官网给的使用说明打开看出来优化器实验步骤&#xff1a; ①构造选择优化器 例如采用随机梯度下降优化器SGD torch.optim.SGD(beyond.parameters(),lr0.01)&#xff0c;放入beyond模型的参数param…

Windows下运行jekyll,编码已不再是问题

很久没更新jekyll了&#xff0c;所以好奇着去官网看了下更新记录&#xff0c;发现如下更新条目&#xff08;版本1.3.0/2013-11-04发布&#xff09;&#xff1a; Add encoding configuration option (#1449)之前在windows下安装jekyll运行编写的代码时&#xff0c;如果有中文&am…

leetcode 滑动窗口小结 (二)

目录424. 替换后的最长重复字符思考分析1优化1004. 最大连续1的个数 III友情提醒方法1&#xff0c;基于当前最大频数方法2&#xff0c;基于历史最大频数424. 替换后的最长重复字符 https://leetcode-cn.com/problems/longest-repeating-character-replacement/ 给你一个仅由大…

软件故障_一些主要的软件故障

软件故障The need for software engineering was realized by the software industry after some of its major failures. Some of these failures are listed below, 在经历了一些重大失败之后&#xff0c;软件行业意识到了对软件工程的需求 。 下面列出了其中一些故障&#x…

十五、修改VGG16网络来适应自己的需求

一、VGG-16 VGG-16神经网络是所训练的数据集为ImageNet ImageNet数据集中验证集和测试集一万五千张&#xff0c;有一千个类别 二、加载VGG-16神经网络模型 VGG16模型使用说明 torchvision.models.vgg16(pretrainedFalse) 其中参数pretrained表示是否下载已经通过ImageNet数…

leetcode 滑动窗口小结 (三)

目录978. 最长湍流子数组题目思路分析以及代码1052. 爱生气的书店老板题目思考分析与初步代码优化思路以及优化代码1208. 尽可能使字符串相等题目思考分析以及代码978. 最长湍流子数组 https://leetcode-cn.com/problems/longest-turbulent-subarray/ 题目 当 A 的子数组 A[…

JAVA多线程学习3--线程一些方法

一、通过sleep方法睡眠 在指定的毫秒数内让当前正在执行的线程休眠&#xff08;暂停执行&#xff09;。该线程不丢失任何监视器的所属权。 二、线程优先级 线程具有优先级&#xff0c;范围为1-10。 MAX_PRIORITY线程可以具有的最高优先级。int类型&#xff0c;值为10. MIN_PRIO…

mcq 队列_MCQ | 量子密码学

mcq 队列1) Which possible Attacks in Quantum Cryptography can take place? 1)量子密码术中可能发生哪些攻击&#xff1f; Possible Attacks in Quantum Cryptography and Birthday Attack 量子密码术和生日攻击的可能攻击 Birthday attack and Boomerang attack 生日袭击…

《inside the c++ object model》读书笔记 之一:对象

关于对象 ...引子:在C语言中,"数据"和"处理数据的操作(函数)"是分开来声明的,语言本身并没有支持"数据和函数"之间关联性,这种程序成为"程序性的",由一组"分布在各个一功能为向导的函数中"的算法驱动,他们处理的是共同的外部…

十六、保存和加载自己所搭建的网络模型

一、保存自己搭建的模型方法一 例如&#xff1a;基于VGG16网络模型架构的基础上加上了一层线性层&#xff0c;最后的输出为10类 torch.save(objmodule,f"path")&#xff0c;传入需要保存的模型名称以及要保存的路径位置 保存模型结构和模型的参数&#xff0c;保存文…

uC/OS-II OS_TASK.C中有关任务管理的函数

函数大致用途 OS_TASK.C是uC/OS-II有关任务管理的文件&#xff0c;它定义了一些函数&#xff1a;建立任务、删除任务、改变任务的优先级、挂起和恢复任务&#xff0c;以及获取有关任务的信息。 函数用途OSTaskCreate()建立任务OSTaskCreateExt()扩展建立任务OSTaskStkChk()堆…

windows下写的脚本,在linux下执行失败

Windows中的换行符为CRLF, 即正则表达式的rn(ASCII码为13和10), 而Unix(或Linux)换行符为LF, 即正则表达式的n. 在Windows和Linux下协同工作的时候, 往往这个细小的差别就导致问题, 如 1)Windows下写的Shell脚本, 在Linux下运行时往往出现rn是无效参数, 不能执行; 2)vi 等编器下…

Scala中的do ... while循环

做...在Scala循环 (do...while loop in Scala) do...while loop in Scala is used to run a block of code multiple numbers of time. The number of executions is defined by an exit condition. If this condition is TRUE the code will run otherwise it runs the first …

十七、完整神经网络模型训练步骤

以CIFAR-10数据集为例&#xff0c;训练自己搭建的神经网络模型架构 一、准备CIFAR-10数据集 CIFAR10官网使用文档 torchvision.datasets.CIFAR10(root"./CIFAR_10",trainTrue,downloadTrue) 参数描述root字符串&#xff0c;指明要下载到的位置&#xff0c;或已有数…

μC/OS-Ⅱ 操作系统内核知识

目录μC/OS-Ⅱ任务调度1.任务控制块2.任务管理3.任务状态μC/OS-Ⅱ时间管理μC/OS-Ⅱ内存管理内存控制块MCBμC/OS-Ⅱ任务通信1.事件2.事件控制块ECB3.信号量4.邮箱5.消息队列操作系统内核&#xff1a;在多任务系统中&#xff0c;提供任务调度与切换、中断服务 操作系统内核为每…

第二版tapout

先说说上次流回来的芯片的测试情况。 4月23日&#xff0c; 芯片采用裸片直接切片&#xff0c; bond在板子上&#xff0c;外面加了一个小塑料壳来保护&#xff0c;我们就直接拿回来测试了。 测试的主要分为模拟和数字两部分&#xff0c; 数字部分的模块基本都工作正常&#xff0…

cd-rom门锁定什么意思_CD-ROM的完整形式是什么?

cd-rom门锁定什么意思CD-ROM&#xff1a;光盘只读存储器 (CD-ROM: Compact Disc Read-Only Memory) CD-ROM is an abbreviation of "Compact Disc Read-Only Memory". It is a data storage memory in the form of an optical compact disc, which is read by a syst…

远程工作时的协作工具

远程工作时的协作工具 Google Hangout 用于日常会议和面对面交谈,在国内其实可以用qq来带起。Campfire 用于一天来的持续对话。Screenhero 用于分享屏幕&#xff0c;一起写代码,这个比较有用,可以一起写代码。Balsamiq 用于计划要制作的 UI。Asana 用于管理任务Google Docs 用于…