leetcode76:最小覆盖字串(滑动窗口)

一:题目

在这里插入图片描述

二:思路

思路拿别人的,感觉写的很nice!! 渣渣杰只能膜拜大佬的了

1.滑动窗口的思想:

left 指针和 ring 指针,保证两个指针之间的字符串包含所需要的全部字符。

2在保证 1 的前提下,

向右移动 left,保证 left 的位置为所需要的字符,这样就实现了最短子串。

例如 :s = ABKKKIWI
t = KIWI
left 应该指向 4 而不是 0、1、2 或 3
因为要返回子串,所以我们不直接记录长度,而是使用 min_left 和 min_right 记录最小窗口的位置。

3.关键问题1:怎么确保当前窗口包含所有需要的字符?

可以使用哈希表来记录,key = 需要的 t 中的所有字符,value = 所需字符的个数

例如:s = ABKKKIWI t = KIWI

t_map[‘K’] = 1;

t_map[‘I’] = 2;

t_map[‘w’] = 1;

当向右移动 right 指针时,只要碰到一个 t 中的字符时,对应的哈希表计数 t_map[s[right]] 就减 1

例如:上面的例子,当 right 指针移动到 7 时,哈希表会变为

t_map[‘K’] = -2;

t_map[‘I’] = 0;

t_map[‘w’] = 0;

当所有哈希表中的计数值都不大于 0 时,说明滑动窗口中已经包含了所有需要的字符串。(等于 0 说明窗口中刚好包含所需要的字符 刚好 2 个 I,小于 0 说明窗口中有多余的 t 中的字符 有多余的 K)

但是判断哈希表全部计数值为 0,并不能在 O(1) 时间内实现(需要遍历),因此我们可以使用一个变量 t_len 来记录遍历过的数组,代表还需要找多少个字符。

right 指针向右移动时,当碰到哈希表中存在的字符,且哈希表中的计数值大于0时,说明这种字符还没找够,此时 t_len -=1,right 进行向右移动。如果碰到的字符对应的计数值已经等于0或者小于0,那么 t_len 不能减 1,因为这种字符已经多余了,但哈希表中的计数要接着减。

当 t_len = 0 时,说明窗口内已经包含全部所需要的字符了,接下来只需要移动 left 指针,使得窗口最小即可。

4:关键问题2:怎么把 left 移动到正确位置?

left 正确位置:使得窗口开头就是需要的字符,且不多余。

例如:s = ABKKKIWIWK t = KIWI 当 right 指针移动到 7 时,哈希表会变为

t_map[‘K’] = -2;

t_map[‘I’] = 0;

t_map[‘w’] = 0;

此时的 left 还指向 0, 我们要缩小窗口,AB很容易,不在哈希表中,直接跳过即可,此时哈希表中的 K 计数小于 0 说明存在多余的 K,我们边缩小窗口(即 left ++) 边增加哈希表中的计数,知道计数为0,说明刚好找到了最后一个K(再缩小就没有 K 了),此时窗口为可能的最小窗口,计算该窗口的长度,比较,更新记录即可。

然后 left++ 跳过这个这个 K,使得窗口继续向右滑动寻找下一个 K,寻找下一个子串。

三:上码(一点也不难也就写了5个小时而已)

class Solution {
public:/**思路:1.滑动窗口类型的题2.滑动窗口的三要素滑动窗口的起始位置 字符串的起始位置滑动窗口的滑动体 在s中包含t的字符串滑动窗口的结束位置 当在s中t中的字符全部都遇到了 那么此位置为结束位置   */string minWindow(string s, string t) {map<char,int> m;//统计t中各个字符的个数,为了可以确保在找到的字符串中 包含t中的所有元素for(int i = 0; i < t.size(); i++) {m[t[i]]++;}int left = 0;int minLeft = 0;int minRight = s.size();int len = t.size();//用于判断找到的字符串中是否包含t的全部元素for(int right = 0; right < s.size(); right++) {//这里表示的是s中的字符在m中,m.find(s[right]) != m.end()  表示存在             if(m.find(s[right]) != m.end()){if(m[s[right]] > 0){len--;//找到一个元素那么t的长度减一   }m[s[right]]--;//这里面m[s[right]] 可能会出现负数 因为s中可能会出现多个相同的和t中相关的字符,       }//说明我们在s找到了一个字符串包含t中的全部字符if(len == 0){//开始移动左指针,移到包含t中字符的 最小位置为止while(m.find(s[left]) == m.end() || m[s[left]] < 0){     if(m.find(s[left]) == m.end()){left++;//说明s中刚开始的字符没在找到的包含t中字符的字符串中}else{m[s[left]]++;left++;//有可能这个字符的在s中有重复的t中的字符,所以我们需要将其加到等于0为止,这是left和right之间包含t中字符的最小个数 }}//更新最小窗口的if(right-left < minRight - minLeft){minLeft = left;minRight =right;}//下一个窗口 也就是包含t中所有字符的另一个字符串m[s[left]]++;//恢复s[left]字符的个数left++;//淘汰找到包含t的字符串中最左边的字符,准备拥抱新的字符串包含t的所有元素 len++;//表示目前的字符串中还差一个字符就可以包含t中的所有字符(为下有一次遍历做准备)}}if(minRight == s.size()){return "";}else{return s.substr(minLeft,minRight-minLeft+1);}}
};

在这里插入图片描述
这个题是今年秋招 字节一面中半个小时需要AC出来的一到原题,我用了5个小时 哈哈哈哈哈哈哈哈 我也就能无奈的笑笑
自己做了3个小时 没做出来 看大佬思路 又学习人家的码 又用了俩小时 菜鸡杰 菜鸡杰 这回菜到家了 。 本来想放弃 但是如果遇到难的就放弃,那就不用学了,越积越多,虽然花的时间长,但是慢慢来 一切都会好的

认怂 复盘 慢慢来 加油 素未谋面的你 晚安!

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

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

相关文章

Orleans 知多少 | Orleans 中文文档上线

Orleans 简介Orleans是一个跨平台框架&#xff0c;用于构建健壮&#xff0c;可扩展的分布式应用程序Orleans建立在.NET开发人员生产力的基础上&#xff0c;并将其带入了分布式应用程序的世界&#xff0c;例如云服务。Orleans可从单个本地服务器扩展到云中全局分布的高可用性应用…

『软件工程12』软件工程实践方法——软件测试

软件工程实践方法—— 软件测试一、软件测试概述1、软件测试的目的&#xff08;1&#xff09;从用户和开发者角度&#xff08;2&#xff09;Myers软件测试目的2、软件测试的原则3、软件测试的对象4、测试信息流5、测试与软件开发各阶段的关系二、软件测试用例1、黑盒测试概述2、…

leetcode59:螺旋矩阵||(思路+详解)

一:题目 二&#xff1a;思路 1.我们需要模拟数字的变化过程, 2.模拟填充的过程:(顺时针) 填充上行 从左到右 填充右行 从上到下 填充下行 从右向左 填充左行 从下到上 3.分析我们填充数字的过程&#xff0c;比如n3的时候 上行:1,2 右行:3,4 下行:5,6 左行:7,8 这么分析下来我们…

在香蕉派的树莓派系统上配置 Syncthing 自启动(暨 Linux 软件自启服务配置)

在香蕉派的树莓派系统上配置 Syncthing 自启动独立观察员 2020 年 1 月 19 日&#xff08;2020年8月30日 更新&#xff09;首先做个名词解释&#xff0c;” 香蕉派” 是国内一款山寨树莓派的硬件产品&#xff0c;” 树莓派系统” 指的是”raspberrypi”&#xff0c;而”Syncthi…

『软件工程13』浅谈面向对象方法,统一建模语言UML

浅谈面向对象方法UML一、UML的含义二、UML的主要内容1、UML的概念模型2、UML概念模型图例三、UML的基本构造块1、UML中的事物&#xff08;1&#xff09;UML中的四种事物&#xff08;2&#xff09;UML中各种事物的图示法2、UML中的四种关系&#xff08;1&#xff09;依赖&#x…

leetcode54:螺旋矩阵

一:题目 二&#xff1a;上码 class Solution { public:vector<int> spiralOrder(vector<vector<int>>& matrix) {vector<int> ans;int startx 0,starty 0;int n matrix.size();//求出行int m matrix[0].size();//求出列int loop m/2 < n/…

查漏补缺方为上策!!两万六字总结vue的基本使用和高级特性,周边插件vuex和vue-router任你挑选

vue的基本使用和高级特性&#xff0c;周边插件vuex和vue-router一、vue的使用1、vue-cli2、基本使用&#xff08;1&#xff09;模板&#xff08;插值&#xff0c;指令&#xff09;&#xff08;2&#xff09;computed和watch&#xff08;3&#xff09;class和style&#xff08;4…

数据库单表千万行 LIKE 搜索优化手记

我们经常在数据库中使用 LIKE 操作符来完成对数据的模糊搜索&#xff0c;LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式。如果需要查找客户表中所有姓氏是“张”的数据&#xff0c;可以使用下面的 SQL 语句&#xff1a;SELECT * FROM Customer WHERE Name LIKE 张%如果需要…

Mybatis第一个程序

一:整体流程 这个流程可以根据官方文档进行编写 mybatis的官方文档 二:实现 1:创建一个表 CREATE DATABASE mybatis;CREATE TABLE user(id INT NOT NULL PRIMARY KEY,name VARCHAR(30) NOT NULL DEFAULT ,pwd VARCHAR(20) NOT NULL DEFAULT )ENGINE INNODB;INSERT I…

基于.NetCore3.1系列 —— 日志记录之初识Serilog

前言对内置日志系统的整体实现进行了介绍之后&#xff0c;可以通过使用内置记录器来实现日志的输出路径。而在实际项目开发中&#xff0c;使用第三方日志框架&#xff08;如&#xff1a;Log4Net、NLog、Loggr、Serilog、Sentry 等&#xff09;来记录也是非常多的。首先一般基础…

手把手教你剖析vue响应式原理,监听数据不再迷茫

Object.defineProperty实现vue响应式原理一、组件化基础1、“很久以前”的组件化&#xff08;1&#xff09;asp jsp php 时代&#xff08;2&#xff09;nodejs2、数据驱动视图&#xff08;MVVM&#xff0c;setState&#xff09;&#xff08;1&#xff09;数据驱动视图 - Vue MV…

leetcode:203. 移除链表元素(两种方法)

一:题目 二:上码 1:方法一&#xff1a;(虚拟一个首结点) class Solution { public:ListNode* removeElements(ListNode* head, int val) {//1.虚拟一个头结点 这样就不用单独处理了ListNode * virtuals new ListNode(0);//给其开辟个空间并且赋初值virtuals->next head…

面试中的网红虚拟DOM,你知多少呢?深入解读diff算法

深入浅出虚拟DOM和diff算法一、虚拟DOM&#xff08;Vitual DOM&#xff09;1、虚拟DOM&#xff08;Vitual DOM&#xff09;和diff的关系2、真实DOM的渲染过程3、虚拟DOM是什么&#xff1f;4、解决方案 - vdom&#xff08;1&#xff09;问题引出&#xff08;2&#xff09;vdom如…

Blazor带我重玩前端(六)

本文主要讨论Blazor事件内容&#xff0c;由于blazor事件部分很多&#xff0c;所以会分成上下两篇&#xff0c;本文为第二篇。双向绑定概述如图所示当点击单项绑定的时候&#xff0c;MyOnewayComponent里的属性值会发生变化&#xff0c;这种变化是单项的&#xff0c;仅仅只是本地…

leetcode707:设计链表(增删差)

一:题目 二:上码 class MyLinkedList { public://定义链表节点结构体struct LinkedNode {int val;LinkedNode* next;LinkedNode(int val):val(val), next(nullptr){}};// 初始化链表MyLinkedList() {node new LinkedNode(0); // 这里定义的头结点 是一个虚拟头结点&#xff0…

深入探究.Net Core Configuration读取配置的优先级

前言在之前的文章.Net Core Configuration源码探究一文中我们曾解读过Configuration的工作原理&#xff0c;也.Net Core Configuration Etcd数据源一文中探讨过为Configuration自定义数据源需要哪些操作。由于Configuration配置系统也是.Net Core的核心&#xff0c;其中也包含了…

TypeScript,从0到入门带你进入类型的世界

从0到入门进入TS的世界一、什么是TypeScript&#xff1f;1、编程语言的类型2、TypeScript究竟是什么&#xff1f;二、为什么要学习TypeScript&#xff1f;1、程序更容易理解2、效率更高3、更少的错误4、非常好的包容性5、一点小缺点三、typescript入门1、如何安装TypeScript2、…

编写第一个 .NET 微服务

介绍本文的目的是&#xff1a;通过创建一个返回列表的简单服务&#xff0c;并在 Docker 容器中运行该服务&#xff0c;让您熟悉使用 .NET 创建微服务的构建过程。安装 .NET SDK要开始构建 .NET 应用程序&#xff0c;首先下载并安装 .NET Core SDK&#xff08;软件开发工具包&am…

模板编译template的背后,究竟发生了什么事?带你了解template的纸短情长

解析模板编译template的背后发生了什么一、&#x1f4d1;初识模板编译1、vue组件中使用render代替template2、模板编译总结二、✏️感受模板编译的美1、with语法&#xff08;1&#xff09;例子展示&#x1f330;&#xff08;2&#xff09;知识点归纳三、&#x1f4c8;编译模板1…

leetcode24. 两两交换链表中的节点(思路+解析)

一:题目 二:思路 思路: 1.分析题意 这是相邻结点进行交换 如果是4个结点 那么1和2交换 3和4交换 如果是3个结点 那么就1和2进行交换 3不动 2.这里我们定义一个虚拟头节点方便操作&#xff0c;我们只需三步实现结点的交换 <1>:让虚拟结点指向第二个结点(进行交换的结点我…