力扣每日一题30:串联所有单词的子串
题目描述
给定一个字符串 s
和一个字符串数组 words
。 words
中所有字符串 长度相同。
s
中的 串联子串 是指一个包含 words
中所有字符串以任意顺序排列连接起来的子串。
- 例如,如果
words = ["ab","cd","ef"]
, 那么"abcdef"
,"abefcd"
,"cdabef"
,"cdefab"
,"efabcd"
, 和"efcdab"
都是串联子串。"acdbef"
不是串联子串,因为他不是任何words
排列的连接。
返回所有串联子串在 s
中的开始索引。你可以以 任意顺序 返回答案。
示例 1:
输入: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] 也是可以的。
示例 2:
输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
输出:[]
解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。
s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。
所以我们返回一个空数组。
示例 3:
输入:s = "barfoofoobarthefoobarman", words = ["bar","foo","the"] 输出:[6,9,12] 解释:因为 words.length == 3 并且 words[i].length == 3,所以串联子串的长度必须为 9。 子串 "foobarthe" 开始位置是 6。它是 words 中以 ["foo","bar","the"] 顺序排列的连接。 子串 "barthefoo" 开始位置是 9。它是 words 中以 ["bar","the","foo"] 顺序排列的连接。 子串 "thefoobar" 开始位置是 12。它是 words 中以 ["the","foo","bar"] 顺序排列的连接。
提示:
1 <= s.length <= 104
1 <= words.length <= 5000
1 <= words[i].length <= 30
words[i]
和s
由小写英文字母组成
请问您在哪类招聘中遇到此题?
1/5
社招
校招
实习
未遇到
通过次数
196.5K
提交次数
502.9K
通过率
39.1%
思路一,暴力遍历,通过178/179
字典(字符串数组)里每个单词的长度是固定的,假设字典里有word_num个单词,每个单词的长度为word_size。那么我们的任务就是在s中找到所有长度为word_num*word_size的子串,判断这个子串能不能由字典里的单词串联起来(其中串联指的是words里面的任意一个排列的连接)。
这个方法的代码比较好写,先用一个哈希表存放字典中每个单词出现的次数。每次判断子串时再创键一个新表,遍历word_num个单词,若某个单词在旧表中没有出现过或者是新表出现次数比旧表的多,就说明这个子串不符合条件。
实现代码:
class Solution {
public:unordered_map<string,int> mp;bool judge(string& s,int wordNumber,int wordLength,int begin)//单词个数,单词的字母个数{unordered_map<string,int> newMp;for(int i=begin;i<begin+wordNumber*wordLength;i+=wordLength){string temp=s.substr(i,wordLength);if(mp.find(temp)==mp.end()) return false;//字符串数组中没出现newMp[temp]++;if(newMp[temp]>mp[temp]) return false;//多出现了}return true;}vector<int> findSubstring(string s, vector<string>& words) {vector<int> ans;for(int i=0;i<words.size();i++){mp[words[i]]++;}int n=words.size(),m=words[0].size(),ls=s.length();int left=0,right=n*m;for(int i=0;i<=ls-n*m;i++){bool flag=judge(s,n,m,i);if(flag) ans.push_back(i);}return ans;}
};
思路二:哈希表+滑动窗口+类KMP思想,全部通过
我们学过kmp算法的都知道,在字符串匹配时(假设是在s串里寻找s1串),如果比较懂s为下标i,s1为下标j的位置时发现两个串暂时不相等,用BF算法的思想来说i要返回到i-j+1的位置,j要回到0的位置(这里假设下标从0开始),然后重新匹配。
但是按照kmp算法的思想来说,既然s1已经比到了下标 j 的位置,那么说明s1的前 j 个字符和s[i]的前j个字符是相等的,而如果s1的最前面 k 个字符和s[i]的前 k 个字符相等的话,i就不用回溯,而 j 只需要回溯到第 k+1 个位置就行。
总而言之,kmp算法最核心的思想就是保留了之前搜索时的信息,方便下一次搜索。
代码:
class Solution {
public:vector<int> findSubstring(string s, vector<string>& words) {vector<int> ans;int word_nums = words.size();int word_size = words[0].size();int ls = s.length();unordered_map<string, int> mp1;for (int i = 0; i < word_nums; i++)mp1[words[i]]++;for (int i = 0; i < word_size; i++){int k;unordered_map<string, int> mp2;bool flag = false;//表示同一个i下,上次匹配成功for (int j = i; j + word_nums * word_size <= ls; j += word_size){//从下标j开始的子串if (!flag) k = j;for (; k < j + word_nums * word_size; k += word_size){string temp = s.substr(k, word_size);if (mp1.find(temp) == mp1.end()) {//下标k之前(包括下标k)开始的子串都不用判断了j = k;//j=k+word_size;外层的循环j还会加一次word_size//之前存储的结果也作废了flag = false;mp2.clear();break;}else {mp2[temp]++;//重复次数过多时,从下表j开始就不行了//重复出现的子串是temp,所以只要从j开始寻找第一次出现temp的位置index,然后从index+word_size开始匹配if (mp2[temp] > mp1[temp]) {int index = j;string t = s.substr(index, word_size);while (t != temp) {index += word_size;mp2[t]--;t = s.substr(index, word_size);}j = index + word_size;//index+=word_size;外层循环会加一次word_sizemp2[temp]--;}}}//从j开始的子串完全匹配if (k == j + word_nums * word_size){ans.push_back(j);//移除从j开始的子串的第一个单词string t = s.substr(j, word_size);mp2[t]--;if (mp2[t] == 0) mp2.erase(t);//k += word_size;//只有一个单词没有匹配好,所以从k就从k+word_size开始flag = true;}}}return ans;}
};
相关文章:
力扣每日一题30:串联所有单词的子串
题目描述 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如,如果 words ["ab","cd","ef"], 那么 &q…...
vim | vim的快捷命令行
快捷进入shell界面 -> :nnoremap <F8> :sh<CR> -> 绑定到了F8 :nnoremap <F8> :sh<CR> 快捷执行 -> :nnoremap <F5> :wa<CR>:!g % -o a.out && ./a.out<CR> -> 绑定到了F5 :nnoremap <F5> :wa<CR>…...
项目管理平台-01-BugClose 入门介绍
拓展阅读 Devops-01-devops 是什么? Devops-02-Jpom 简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件 代码质量管理 SonarQube-01-入门介绍 项目管理平台-01-jira 入门介绍 缺陷跟踪管理系统,为针对缺陷管理、任务追踪和项目管理的商业…...

web集群-lvs-DR模式基本配置
目录 环境: 一、配置RS 1、安装常见软件 2、配置web服务 3、添加vip 4、arp抑制 二、配置LVS 1、添加vip 2、安装配置工具 3、配置DR 三、测试 四、脚本方式配置 1、LVS-DR 2、LVS-RS 环境: master lvs 192.168.80.161 no…...

基于深度学习的面部情绪识别算法仿真与分析
声明:以下内容均属于本人本科论文内容,禁止盗用,否则将追究相关责任 基于深度学习的面部情绪识别算法仿真与分析 摘要结果分析1、本次设计通过网络爬虫技术获取了七种面部情绪图片:吃惊、恐惧、厌恶、高兴、伤心、愤怒、自然各若…...
C语言经典面试题目(十六)
1、什么是C语言中的指针常量和指针变量?它们有什么区别? 在C语言中,指针常量和指针变量是指针的两种不同类型。它们的区别在于指针的指向和指针本身是否可以被修改。 指针常量:指针指向的内存地址不可变,但指针本身的…...

【C语言】文件操作揭秘:C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】
欢迎来CILMY23的博客喔,本篇为【C语言】文件操作揭秘:C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】,感谢观看,支持的可以给个一键三连,点赞关注收藏。 前言 欢迎来到本篇博客&…...
JAVA八股文面经问题整理第6弹
文章目录 目录 文章目录 提问问题 问题1 问题2 问题3 问题4 问题5 问题6 问题7 问题8 问题9 问题10 问题11 问题12 写在最后 提问问题 介绍一下Linux常⽤命令,例如:Vim快捷键,常⽤查看Log的命令,路径相关&#x…...
pytest相关面试题
pytest是什么?它有什么优点? pytest是一个非常流行的Python测试框架,它具有简洁、易用、高校等优点。他可以帮助测试人员方便地编写和运行测试用例,并且提供了丰富的插件和扩展,支持各种测试需求介绍下pytest常用的库 …...
Keras库搭建神经网络
Keras并非简单的神经网络库,而是一个基于Theano的强大的深度学习库,利用它不仅仅可以搭建普通的神经网络,还可以搭建各种深度学习模型,如自编码器、循环神经网络、递归神经网络、卷积神经网络等。 安装代码: pip ins…...

适配器模式与桥接模式-灵活应对变化的两种设计策略大比拼
🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》 💪🏻 制定明确可量化的目标,坚持默默的做事。 🚀 转载自:设计模式深度解析:适配器模式与桥接模式-灵活应对变…...
Elasticsearch8搭建及Springboot中集成使用
1.搭建 1.1.下载地址 Elasticsearch:https://www.elastic.co/cn/downloads/elasticsearch Kibana:https://www.elastic.co/cn/downloads/kibana 1.2.具体过程 下载安装包:访问上述链接,下载适合你操作系统的Elasticsearch和Ki…...

asp.net在线租车平台
说明文档 运行前附加数据库.mdf(或sql生成数据库) 主要技术: 基于asp.net架构和sql server数据库 功能模块: asp.net在线租车平台 用户功能有首页 行业新闻用户注册车辆查询租车介绍访问后台 后台管理员可以进行用户管理 管…...

Beamer模板——基于LaTeX制作学术PPT
Beamer模板——基于LaTeX制作学术PPT 介绍Beamer的基本使用安装和编译用于学术汇报的模板项目代码模板效果图 Beamer的高级特性动态效果分栏布局定理环境 介绍 在学术领域,演示文稿是展示和讨论研究成果的重要方式。传统的PowerPoint虽然方便,但在处理复…...

性能测试-Jmeter中IF控制器使用
一、Jmeter控制器 分为两种类型: 控制测试计划执行过程中节点的逻辑执行顺序,如:循环控制器,if控制器等对测试计划中的脚本进行分组,方便Jmeter统计执行结果以及进行脚本的运行时控制等,如:吞…...

华为综合案例-普通WLAN全覆盖配置(2)
组网图 结果验证 在AC_1和AC_2上执行display ap all命令,检查当前AP的状态,显示以下信息表示AP上线成功。[AC_1] display ap all Total AP information: nor : normal [1] ExtraInfo : Extra information P : insufficient power supply ---…...

这里是一本关于 DevOps 企业级 CI/CD 实战的书籍...
文章目录 📋 前言🎯 什么是 DevOps🎯 什么是 CI/CD🎯什么是 Jenkins🧩 Jenkins 简单案例 🎯 DevOps 企业级实战书籍推荐🔥 参与方式 📋 前言 企业级 CI/CD 实战是一个涉及到软件开发…...
机器学习 - save和load训练好的模型
如果已经训练好了一个模型,你就可以save和load这模型。 For saving and loading models in PyTorch, there are three main methods you should be aware of. PyTorch methodWhat does it do?torch.saveSaves a serialized object to disk using Python’s pickl…...

【动态规划】【同余前缀和】【多重背包】[推荐]2902. 和带限制的子多重集合的数目
本文涉及知识点 动态规划汇总 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 C算法:滑动窗口总结 多重背包 LeetCode2902. 和带限制的子多重集合的数目 给你一个下标从 0 开始的非负整数数组 nums 和两个整数 l 和 r 。 请你…...

nginx介绍及搭建
架构模型 Nginx是由一个master管理进程、多个worker进程组成的多进程模型。master负责管理worker进程,worker进程负责处理网络事件,整个框架被设计为一种依赖事件驱动、异步、非阻塞的模式。 优势: 1、充分利用多核,增强并发处理…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...

C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...