【刷题】滑动窗口精通 — Leetcode 30. 串联所有单词的子串 | Leetcode 76. 最小覆盖子串

news/2024/4/28 17:09:59/文章来源:https://blog.csdn.net/JLX_1/article/details/137017257

在这里插入图片描述
送给大家一句话:

充满着欢乐与斗争精神的人们,永远带着欢乐,欢迎雷霆与阳光。 —— 赫胥黎

滑动窗口精通

  • 前言
  • Leetcode 30. 串联所有单词的子串
    • 题目描述
    • 算法思路
  • Leetcode 76. 最小覆盖子串
    • 题目描述
    • 算法思路
  • Thanks♪(・ω・)ノ 谢谢阅读!!!
  • 下一篇文章见!!!

前言

相信通过前两篇的文章的讲解,大家已经对滑动窗口有了较深的认识,今天我们来挑战一下!!!
来做两道困难级的题目。

Leetcode 30. 串联所有单词的子串

家人们!!!上链接!!!30. 串联所有单词的子串

题目描述

在这里插入图片描述
根据题目描述,这道题看起来很是复杂呢!?!?
我们要在一个字符串中寻找包含words的所有单词的子串,并会返回对应的开始位置(开始索引)。看这描述十分类似这道题目 438. 找到字符串中所有字母异位词 ,一个是寻找异位词,一个是寻找"异位单词串"。本质是十分相似的。
来看一个样例:

  • 输入:s = “barfoothefoobarman”, words = [“foo”,“bar”]
  • 输出:[0,9]
  • 解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。
    子串 “barfoo” 开始位置是 0。它是 words 中以 [“bar”,“foo”] 顺序排列的连接。
    子串 “foobar” 开始位置是 9。它是 words 中以 [“foo”,“bar”] 顺序排列的连接。
  • 输出顺序无关紧要。返回 [9,0] 也是可以的。

根据这样例,更容易想象为是如同字母一样。

算法思路

我们先把每个单词抽象为一个字母(方便我们梳理思路),我们只需要找到一个子串中有所有的“字母”即可。
那么,我们来看最简单的算法:暴力枚举。就是遍历所有的子串,以样例来说:

  1. bar foo the foo bar man (注意步长是单词的长度),从左到右依次遍历,寻找满足条件的子串。

  2. 我们来思考一下,当该躺不满足条件时:
    在这里插入图片描述

    很明显,无需把right重新移动的到left的位置重新开始,直接继续进行移动就可以。

  3. 所以此时构成滑动窗口的条件两个指针移动方向一致

那么我们就按照滑动窗口的解题模版来思考细节:

  • 进窗口
  • 判断
  • 出窗口
  • 更新结果(位置待定)

首先我们要解决的是个一般性问题:s 字符串的长度一定是单词的整数倍吗???
显然不是!
那么就要进行多次滑动窗口!保证可以遍历到所有可能的子串。那进行几次呢???
在这里插入图片描述

可以看出来只需要进行单词个数次的循环即可!!!再多就发生重复了!

这样大致的框架就有了,剩下的就是然后判断单词是否满足条件。
依旧时候使用哈希算法,利用无向图来模拟哈希表(string 映射 int)。

class Solution {
public:vector<int> findSubstring(string s, vector<string>& words) {//预备工作//哈希表1unordered_map<string,int> hash1;for(auto ch : words) hash1[ch] ++; //对words进行处理// 基本变量int len = words[0].size(); //单词长度(步长) int m = words.size();//单词个数int n = s.size();//字符串长度//答案vector<int> ans;//多次进行滑动窗口for(int i = 0;i < len;i++){//哈希表2 用来进行比较unordered_map<string,int> hash2;//进窗口 注意一次移动的步长 注意结束条件(保证最后一个是完整单词,不然会发生越界)for(int left = i ,right = i ,count = 0; right + len <= n ; right += len ){string in = s.substr(right,len);//进窗口 维护count++ (有效单词数加一)if(++hash2[in] <= hash1[in]){count++;}//判断是否超出长度if(right - left + 1 > m * len){string out = s.substr(left,len);//出窗口 维护countif(hash2[out]-- <= hash1[out]) count--;left += len;}//满足条件  更新结果if(count == m){ans.push_back(left);}} }return ans;}
};

我们提交:过啦!!!!

Leetcode 76. 最小覆盖子串

家人们!!! 上链接!!!76. 最小覆盖子串

题目描述

在这里插入图片描述
根据题目描述,我们需要再字符串中寻找能够覆盖 t 中所有字符的 最短子串,这个“覆盖”是包含 t 中的每个字母,不用管顺序。来看样例:

  • 输入:s = “ADOBECODEBANC”, t = “ABC”
  • 输出:“BANC”
  • 解释:最小覆盖子串 “BANC” 包含来自字符串 t 的 ‘A’、‘B’ 和 ‘C’。

看了样例,应该就理解了这个“覆盖”:

  1. 对应字母个数必须大于等于 t 中字母个数
  2. 可以包含其它字母

算法思路

先来最直接的办法 — 暴力枚举,我们来看暴力算法是如何进行的:

  1. 首先找到一个包含于 t 的字母
  2. 然后从这个位置开始遍历
  3. 直到满足 t 中的每个字母都能在该子串中找到
  4. 然后再找到下一个包含于 t 的字母 重复 1 - 3

这样就完成了任务,那么如何进行优化呢???
根据暴力的步骤,我们可以看出来两个指针的移动方向是一致的,所以就可以进行滑动窗口算法了。
那么我们就按照滑动窗口的解题模版来思考细节:

  • 进窗口
  • 判断
  • 出窗口
  • 更新结果(位置待定)

这个判断要怎样进行判断???
肯定是使用哈希算法,但是如何保证对应字母个数必须大于等于 t 中字母个数呢???
这一步与之前的判断略有不同,因为我们可以多字母,来看代码:

class Solution {
public:string minWindow(string s, string t) {//滑动窗口 + 哈希算法//准备工作int kinds = 0; //字母种类 方便判断int hash1[128] = {0}; //哈希表1 因为只有使用数组比较方便//遍历所有字母 确定个数for (auto ch : t) if (hash1[ch]++ == 0) kinds++;// 长度 int n = s.size();//哈希表2 用来比较int hash2[128] = { 0 }; int begin = -1 ,minlen = INT_MAX;for(int left = 0,right = 0 ,count = 0;right < n;right++){char in = s[right];//进窗口 维护count (对应字母相等时更新 保证满足条件 有效字母加一)if(++hash2[in] == hash1[in]) count++;//判断while(count == kinds){//更新结果if(right - left + 1 < minlen){minlen = right - left + 1;begin = left;}char out = s[left];//出窗口 维护count (相等时出窗口 有效字母减少)if(hash2[out]-- == hash1[out]) count--;left++;}}return begin == -1 ? "" : s.substr(begin,minlen);}
};

提交:过啦!!!!!!

经过这两道题目的书写,相信大家一定深刻认识到了滑动窗口的使用方法!!!
下面请大家继续刷题吧!!!

Thanks♪(・ω・)ノ 谢谢阅读!!!

下一篇文章见!!!

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

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

相关文章

45.跳跃游戏||

// 定义一个名为Solution的类 class Solution {// 定义一个public方法jump&#xff0c;输入参数为一个整数数组nums&#xff0c;返回值类型为整数public int jump(int[] nums) {// 初始化跳跃次数结果变量为0int result 0;// 初始化当前覆盖的最远距离下标为0int end 0;// 初…

【随笔】Git -- 基本概念和使用方式(五)

&#x1f48c; 所属专栏&#xff1a;【Git】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大…

安卓利用CameraX 拍照获这张照片的exif信息

一、首先导入相关权限 <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE" /><uses-featureandroid:name"android.hardware.camera"android:required"true" /><uses-permission android:name"andro…

2014年认证杯SPSSPRO杯数学建模B题(第一阶段)位图的处理算法全过程文档及程序

2014年认证杯SPSSPRO杯数学建模 B题 位图的处理算法 原题再现&#xff1a; 图形&#xff08;或图像&#xff09;在计算机里主要有两种存储和表示方法。矢量图是使用点、直线或多边形等基于数学方程的几何对象来描述图形&#xff0c;位图则使用像素来描述图像。一般来说&#…

Leetcode LRU---哈希➕双链表

题目链接 讲解视频 Tips&#xff1a; 代码&#xff1a; import java.util.*; // 修改导入语句&#xff0c;正确引入 java.util 包class Node{//双链表int key,value;Node pre,next;public Node(int k,int v){this.key k;this.value v;this.pre null;this.next null;}…

OpenHarmony实战开发-从0到1实现购物应用页面

概述 OpenHarmony ArkUI框架提供了丰富的动画组件和接口&#xff0c;开发者可以根据实际场景和开发需求&#xff0c;选用丰富的动画组件和接口来实现不同的动画效果。 本Codelab中&#xff0c;我们会构建一个简易的购物应用。应用包含两级页面&#xff0c;分别是主页&#xf…

【Nebula笔记】基础操作

目录 一、预备~ 二、基础操作 (一) 图空间 1. 创建图空间 2. 清空图空间 3. 其他 4. FAQ 执行DROP SPACE语句删除图空间后&#xff0c;为什么磁盘的大小没变化&#xff1f; (二) 点类型 1. 创建Tag 2. 删除Tag 3. 更新Tag 4. 其他 (三) 边类型 1. 创建Edge type…

ubuntu系统下如何使用vscode编译和调试#小白入门#

编程环境&#xff1a;ubuntu系统为18.04.1&#xff0c;vscode版本为1.66.2 一、VSCode切换中文显示&#xff1a; 1、vscode安装完成后启动,在左侧externsions中搜索“简体中文”插件&#xff0c;并完成安装&#xff1a; 2、选择右下角齿轮形状的"Manage"&#xff…

自然指数函数e^x与欧拉数e (下)

自然指数函数e^x与欧拉数e Part I: 如何找到欧拉数e 上一篇文章停在了“应该存在一个b&#xff0c;使得指数函数b^x在x0处的导数为1。且该指数函数在任意一处的导数都等于当前位置的函数值”。根据前面所知道的&#xff0c;可以用数学公式列出以下一些已知条件&#xff1a; &am…

Go语言学习Day5:函数(下)

名人说&#xff1a;莫愁千里路&#xff0c;自有到来风。 ——钱珝 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 1、本质、数据类型与延迟函数①函数的本质②函数的数据类型③defer延迟函数 2、匿名、回调函数与闭…

Go——map操作及原理

一.map介绍和使用 map是一种无序的基于key-value的数据结构&#xff0c;Go语言的map是引用类型&#xff0c;必须初始化才可以使用。 1. 定义 Go语言中&#xff0c;map类型语法如下&#xff1a; map[KeyType]ValueType KeyType表示键类型ValueType表示值类型 map类型的变量默认…

班级综合测评管理系统的设计与实现|Springboot+ Mysql+Java+ B/S结构(可运行源码+数据库+设计文档)

本项目包含可运行源码数据库LW&#xff0c;文末可获取本项目的所有资料。 推荐阅读100套最新项目持续更新中..... 2024年计算机毕业论文&#xff08;设计&#xff09;学生选题参考合集推荐收藏&#xff08;包含Springboot、jsp、ssmvue等技术项目合集&#xff09; 目录 1. …

docker 的网络管理

docker应用自带了三种类型的网络&#xff0c;然后我们自己也能自定义网络 roottest-virtual-machine:~# docker network ls NETWORK ID NAME DRIVER SCOPE 4c3e28760cff bridge bridge local afd1493dc119 host host local 5f200e2eaf22 n…

AOP切入点表达式基本格式

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 官方地址 https://docs.spring.io/spring-framework/reference/core/aop/ataspectj/pointcuts.html AOP切入点表达式基本格式如下&#xff1a; execution(modifiers-patte…

Vscode创建php项目

1.安装中文插件&#xff08;可安装可不安装&#xff09; 2.安装主题&#xff08;可安装可不安装&#xff09; 3.安装和php相关的插件 4.打开文件夹 5.路由操作 查看项目中的route路由 浏览器中访问think 隐藏index.php入口文件 访问ThinkPHP5.1开发手册&#xff0c;复制apa…

React-1-jsx基础-事件绑定-样式处理

一.JSX基础-概念和本质 1.1 什么是JSX JSX是JavaScript和XML&#xff08;HTML&#xff09;的缩写&#xff0c;表示在JS代码中编写HTML模版结构,它是React中编写UI模版的方式 优势&#xff1a; 1. HTML的声明式模版写法 2. JS的可编程能力 JSX的本质&#xff1a; JSX并不是标…

[openGL] qt5版本+mingw编译Assimp库+调用

目录 一 版本 二 编译问题 三 CMAKE准备 四 开始编译 4.1 准备Assimp源码 4.2 编译工具准备 4.3 生成Assimp库 4.4 使用Assimp 4.4.1 准备 4.4.2 加载模型 4.4.3 模型效果 一 版本 Assimp官网上已经停止更新截至在3.3.1版本,但是这个版本编译是最稳定的,较新的版本…

WORDPRESS从WORD复制粘贴公式

整合教程&#xff1a;WordPress插件包整合教程 WordPaster支持自动上传本地图片文件&#xff0c;自动上传Word文档中的图片 步骤与效果&#xff1a; 1.打开word文档&#xff0c;复制word文档内容 2.在网页中打开编辑器页面&#xff0c;点击“粘贴本地文件,Word文档”按钮上传…

GBase8a-GDCA认证考试-复习参考题

个人能力有限&#xff0c;正确率97%&#xff08;97分&#xff09;。 请注意甄别&#xff0c;根据所学知识综合判断&#xff0c;欢迎指出错误答案。 欢迎学习天津南大通用数据技术股份有限公司|GBASE-致力于成为用户最信赖的数据库产品供应商 免费参加认证培训&#xff1a;为…

Visio中存在问题的解决方法

公式缩放 mathtype公式在visio缩放之后&#xff0c;出现了变形。 解决方法&#xff1a;每次输入公式都通过 插入->对象->mathType Equation 新建一个公式。可以避免 注&#xff1a;网上有的说在word中使用mathtype编写公式&#xff0c;之后复制到visio中。 插入波形 选择…