【LeetCode】30.串联所有单词的子串

news2025/1/11 4:22:21

串联所有单词的子串

题目描述:

给定一个字符串 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"] 顺序排列的连接。

思路分析:

滑动窗口法

什么是滑动窗口法?

        滑动窗口,可以用来解决一些查找满足一定条件的连续区间的性质(长度等)的问题。由于区间连续,因此当区间发生变化时,可以通过旧有的计算结果对搜索空间进行剪枝,这样便减少了重复计算,降低了时间复杂度。往往类似于“请找到满足xx的最x的区间(子串、子数组)的xx”这类问题都可以使用该方法进行解决。

一般滑动窗口维护两个指针,左指针和右指针。

当窗口内的元素未达到题目条件时,右指针右移,探索未知的区间来满足条件
当窗口内的元素达到题目条件时,左指针右移,压缩区间,使窗口尽可能短得满足题目条件

滑动窗口常规模板:

int slidingWindow(vector<int> nums) {
    int n = nums.size();
    int ans = 0;
    // 记录窗口内的元素及其个数,非必要
    map<int, int> um;
    // l:窗口左边界; r:窗口右边界
    int l = 0, r = 0;
    // r 指针负责探索新的区间,直到搜索到nums的某末尾
    while (r < n) {
        um[r]++;
        // 如果区间不满足条件,l指针右移,窗口收缩
        while(区间 [l, r] is Invalid) {
            um[l]--;
            l++;
        }
        // 此处处理结果, deal with(ans, 区间[l, r])
        res = max(ans, r - l + 1); // 或者res = min(ans, r - l + 1);
        // 右指针右移,继续搜索
        r++;
    }
    return ans;
}

代码实现注解:

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        // 单词的数量
        int allCount = words.length;
        // 单个单词的长度
        int aloneLen = words[0].length();
        List<Integer> ret = new ArrayList<>();
        //当遍历长度超过整个字符串的长度推出循环
        for (int i = 0; i < aloneLen; i++) {
            //Map集合获取键值对,map表示滑动窗口中的单词频次和words中的单词频率之差,string收集在words中出现的单词,int收集出现频率
            Map<String, Integer> map = new HashMap<>();
            //遍历words中的word,对窗口里的每个单词计算差值
            for (String word : words) {
                map.put(word, map.getOrDefault(word, 0) + 1);
            }
            // 左边界,起始下标
            int left = i;
            // 右边界
            int right = i;
            // 当前匹配上的单词数量
            int curCount = 0;
            //开始滑动窗口
            while (right <= s.length() - aloneLen) {
                //code用来存放即将进入窗口的单词
                String code = s.substring(right, right + aloneLen);
                //用于计录该单词需要的次数
                Integer cnt = map.getOrDefault(code, 0);
                if (cnt > 0) {
                    // 右边的单词滑进来,并减数量
                    curCount++;
                    map.put(code, cnt - 1);
                    right += aloneLen;
                    if (curCount == allCount) {
                        ret.add(left);
                    }
                } else {
                    // 如果没有剩余且有消耗,左边的单词滑出去
                    if (curCount > 0) {
                        String preCode = s.substring(left, left + aloneLen);
                        map.put(preCode, map.get(preCode) + 1);
                        left += aloneLen;
                        curCount--;
                    } else {
                        // 这里增长 aloneLen,是一个单词的长度
                        left += aloneLen;
                        right += aloneLen;
                    }
                }
            }
        }
        return ret;
    }
}

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

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

相关文章

【智能算法应用】北方苍鹰算法求解二维栅格路径规划问题

目录 1.算法原理2.二维路径规划数学模型3.结果展示4.参考文献5.代码获取 1.算法原理 【智能算法】北方苍鹰优化算法&#xff08;NGO)原理及实现 2.二维路径规划数学模型 栅格法模型最早由 W.E. Howden 于 1968 年提出&#xff0c;障碍物的栅格用黑色表示&#xff0c;可通过的…

草图大师怎么去画好一个建筑别墅su模型呢?

其实&#xff0c;我们经常画别墅的时候&#xff0c;都会要画别墅&#xff0c;我们画一个欧式风格的别墅&#xff0c;要在草图大师中创建一个优秀的建筑别墅模型&#xff0c;可以按照以下步骤进行&#xff1a; skp模型库 1.收集参考资料&#xff1a; 在开始之前&#xff0c;收集…

当前时机是否适合进入 AIGC 行业:行业发展与市场需求分析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

如何成为成功的AI产品经理

本文目录 1 AI产品经理的角色和职责 2 AI产品经理的必备知识技能 3 案例分析 4 总结一下 随着ChatGPT的大热&#xff0c;也带动今年的AI火了一把&#xff0c;很多公司都开始进行相关部署&#xff0c;自然产生了很多岗位需求。 来源&#xff1a;BOSS直聘 那么&#xff0c;要想当…

Training-Free Consistent Text-to-Image Generation # 论文阅读

URL https://arxiv.org/pdf/2402.03286 TL;DR 2024 年 2 月 nvidia 的文章。提出了一种不需要任何额外训练的主体保持方法&#xff0c;可以一次生成的 batch 中&#xff0c;通过多个 prompt 生成对应的多张图片&#xff0c;这些图片都可以拥有一个主体。 本文提出的方法通过…

【JavaEE 初阶(十)】JVM

❣博主主页: 33的博客❣ ▶️文章专栏分类:JavaEE◀️ &#x1f69a;我的代码仓库: 33的代码仓库&#x1f69a; &#x1faf5;&#x1faf5;&#x1faf5;关注我带你了解更多进阶知识 目录 1.前言2.JVM内存区域划分3.类加载3.1双亲委派模型 4.垃圾回收&#xff08;GC&#xff0…

游戏后台开发技术全面解析

在这个数字时代&#xff0c;游戏产业已经成为全球最受欢迎的娱乐方式之一。从简单的手机游戏到复杂的大型多人在线角色扮演游戏&#xff08;MMORPG&#xff09;&#xff0c;游戏的世界正变得越来越丰富和多样化。而这一切的背后&#xff0c;都离不开强大的游戏后台技术支持。在…

心理咨询系统|心理咨询系统开发|心理咨询软件开发

在快节奏的现代生活中&#xff0c;心理健康问题越来越受到人们的关注。为了有效应对这些问题&#xff0c;心理咨询系统应运而生&#xff0c;它为人们提供了一个安全、便捷的平台&#xff0c;以寻求心理帮助和支持。本文将详细介绍心理咨询系统的功能、优势以及未来发展趋势。 …

【C语言】指针运算

前言 前面在“走进指针世界”中我已经讲解过指针相关的很多前置知识&#xff0c;其实还有一个很重要的部分就是指针的运算。这篇博客&#xff0c;就让我们一起了解一下指针的运算吧&#xff01; 指针作为变量&#xff0c;是可以进行算术运算的&#xff0c;只不过情况会和整型…

2024年5月23日 (周四) 叶子游戏新闻

《Unclogged》Steam页面上线 马桶主题恐怖逃脱解谜Brody制作并发行&#xff0c;一款奇葩创意马桶主题恐怖逃脱解谜新游《Unclogged》Steam页面上线&#xff0c;本作暂不支持中文。 Meta人工智能主管杨立昆 大语言模型不会达到人类智能水平IT之家今日&#xff08;5月23日&#x…

JavaScript-数组的增删改查

数组的操作一共有四种&#xff1a; 查询数组数据修改数组中元素的值数组添加新的数据删除数组中的元素 数组的初始化 有些编程语言的数组初始化是用{}包着的&#xff0c;而JS的数组初始化用[] let num[2,6,1,77,52,25,7]; 数组的查询 想要具体查询数组中的某个元素 可以用数…

【C#上位机应用开发实战】—— 通信模块的基础与实践

&#x1f680; 引言 在工业自动化、设备监控、物联网&#xff08;IoT&#xff09;等领域&#xff0c;上位机软件扮演着至关重要的角色。作为连接人与设备的桥梁&#xff0c;上位机软件不仅需要提供友好的用户界面&#xff0c;更需要具备高效、稳定的通信能力。今天&#xff0c…

1105: 交换二叉树的孩子结点

解法&#xff1a; #include<iostream> using namespace std; struct treeNode {char val;treeNode* left, * right;treeNode(char x) :val(x), left(NULL), right(NULL) {}; }; treeNode* buildtree() {char ch;cin >> ch;if (ch #) return NULL;treeNode* r ne…

【机器学习聚类算法实战-4】机器学习聚类算法之k-均值聚类、分层聚类算法、凝聚聚类和谱聚类实例分析

&#x1f3a9; 欢迎来到技术探索的奇幻世界&#x1f468;‍&#x1f4bb; &#x1f4dc; 个人主页&#xff1a;一伦明悦-CSDN博客 ✍&#x1f3fb; 作者简介&#xff1a; C软件开发、Python机器学习爱好者 &#x1f5e3;️ 互动与支持&#xff1a;&#x1f4ac;评论 &…

每日AIGC最新进展(10):符号音乐生成SYMPLEX、新型图像编辑数据集ReasonPix2Pix、角色一致性插画生成、高级的风格个性化扩散模型

Diffusion Models专栏文章汇总&#xff1a;入门与实战 SYMPLEX: Controllable Symbolic Music Generation using Simplex Diffusion with Vocabulary Priors http://arxiv.org/abs/2405.12666v1 本文介绍了一种新的符号音乐生成方法&#xff0c;名为SYMPLEX&#xff0c;它基于…

RAC11G添加节点

添加节点场景 1、集群扩容 2、节点损坏后进行了删除操作&#xff0c;之后又要求恢复删除节点 环境和需求说明 由于3节点RAC&#xff0c;其中节点3因为本地盘损坏&#xff0c;导致系统完全损坏&#xff0c;系统需要重新安装。将损坏的3节点删除后再进行添加。 数据库版本&a…

视觉检测实战项目——九点标定

本文介绍九点标定方法 已知 9 个点的图像坐标和对应的机械坐标,直接计算转换矩阵,核心原理即最小二乘拟合 {𝑥′=𝑎𝑥+𝑏𝑦+𝑐𝑦′=𝑎′𝑥+𝑏′𝑦+𝑐′ [𝑥1𝑦11𝑥2𝑦21⋮⋮⋮𝑥9𝑦91][𝑎𝑎′𝑏𝑏′𝑐𝑐′]=[𝑥1′𝑦…

基于FPGA的VGA协议实现

文章目录 一 VGA相关介绍二 结果演示三 思路整理四 代码编写3.1 时钟分频3.2 添加ROM IP3.2 VGA驱动3.3 Data驱动 源码参考资料总结 一 VGA相关介绍 以下内容来源百度以及https://blog.csdn.net/Learning1232/article/details/131126352?spm1001.2014.3001.5502博客&#xff…

01.msf

文章目录 永恒之蓝下载msfconsolemsfvenom 永恒之蓝 下载 msdn.itellyou.cn msfconsole M e t a s p l o i t C y b e r M i s s i l e C o m m a n d Metasploit Cyber Missile Command MetasploitCyberMissileCommand 的简称 search ms17_010 use 0 或者 use exploit/wind…

嵌入式全栈开发学习笔记---C语言笔试复习大全20

目录 指针数组 数组指针 指针和二维数组 通过指针访问二维数组 通过数组指针访问二维数组 用指针表示二维数组并访问 地址等级 0级地址&#xff1a; 一级地址&#xff1a; 二级地址&#xff1a; 三级地址&#xff1a; 总结 指针的指针 命令行参数 上一篇复习了指…