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

问题描述

给定一个字符串 s 和一个字符串数组 words words 中所有字符串 长度相同

 s 中的 串联子串 是指一个包含  words 中所有字符串以任意顺序排列连接起来的子串。

  • 例如,如果 words = ["ab","cd","ef"], 那么 "abcdef", "abefcd""cdabef", "cdefab""efabcd", 和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。

返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。

解题思路

1. 初步理解

首先需要明确,只有当 s 中的某个子串正好由 words 中所有单词组成,并且每个单词出现一次,才符合条件。这提示我们可以使用组合和检查的策略来找到这些子串。

2. 设计策略

基于以上理解,可以采用以下策略:

  • 长度计算: 计算 words 中所有字符串连接后的总长度,这将是我们在 s 中搜索的子串的长度。
  • 字典统计: 使用一个哈希表(字典)来统计 words 数组中每个单词的出现频率。
  • 滑动窗口: 在字符串 s 上滑动一个固定大小的窗口,并在窗口内部维护一个字典来记录当前窗口中各单词的出现频率。
  • 窗口调整: 根据窗口内单词的实际出现情况,调整窗口的开始位置,确保窗口内的单词频率与 words 中的单词频率相匹配。

3. 实现细节

  • 初始化: 计算每个单词的长度 wordLength,所有单词的数量 wordCount,以及应搜索的窗口大小 windowSize
  • 遍历: 遍历字符串 s 的每个可能的起始位置,步长为 wordLength
  • 内部循环: 对每个起始位置,向右滑动窗口,每次移动一个单词的长度,直到窗口尾部超出字符串 s 的边界。
  • 检查与调整: 每次窗口滑动后,更新当前单词在窗口中的计数,并与 words 字典进行比较,如果当前单词计数超过了应有的频率,则调整窗口的左边界,直至窗口内的单词频率再次符合要求。
  • 记录结果: 如果窗口大小达到了 windowSize,且窗口内的单词与 words 中的单词完全匹配,则记录当前窗口的起始位置。

代码实现

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> indices;
        if (s.empty() || words.empty())
            return indices;

        int wordLength = words[0].size();
        int wordCount = words.size();
        int windowSize = wordLength * wordCount;

        if (s.size() < windowSize)
            return indices;

        // 记录words中每个单词出现的次数
        unordered_map<string, int> wordMap;
        for (const string& word : words) {
            ++wordMap[word];
        }

        // 检查每个可能的开始位置
        for (int i = 0; i < wordLength; ++i) {
            int left = i;
            int right = i;
            unordered_map<string, int> currentMap;

            while (right + wordLength <= s.size()) {
                string word = s.substr(right, wordLength);
                right += wordLength;

                if (wordMap.find(word) != wordMap.end()) {
                    ++currentMap[word];

                    // 处理单词出现次数过多的情况
                    while (currentMap[word] > wordMap[word]) {
                        string leftWord = s.substr(left, wordLength);
                        --currentMap[leftWord];
                        left += wordLength;
                    }

                    // 检查是否形成了一个有效的窗口
                    if (right - left == windowSize) {
                        indices.push_back(left);
                        string leftWord = s.substr(left, wordLength);
                        --currentMap[leftWord];
                        left += wordLength;
                    }
                } else {
                    currentMap.clear();
                    left = right;
                }
            }
        }

        return indices;
    }
};

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

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

相关文章

【Nginx】源码安装

nginx官网&#xff1a;nginx: download 选择文档版本安装即可 1.安装依赖包 //一键安装上面四个依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 2.下载并解压安装包 //创建一个文件夹 cd /usr/local mkdir nginx cd nginx //将下载的nginx压缩…

Linux(Ubuntu20.04)系统中安装deb软件包错误(依赖关系问题-仍未被配置)解决的办法

在Ubuntu16.04下采用如下dpkg命令安装deb软件安装包时&#xff1a; sudo dpkg -i XXXX.deb 发生安装失败&#xff0c;返回信息为&#xff02;正处理时有错误发生&#xff02;&#xff0c;并且在安装过程中出现&#xff02;依赖关系问题-仍未被配置&#xff02;的提示&#xff0…

240629_昇思学习打卡-Day11-Vision Transformer中的self-Attention

240629_昇思学习打卡-Day11-Transformer中的self-Attention 根据昇思课程顺序来看呢&#xff0c;今儿应该看Vision Transformer图像分类这里了&#xff0c;但是大概看了一下官方api&#xff0c;发现我还是太笨了&#xff0c;看不太明白。正巧昨天学SSD的时候不是参考了太阳花的…

编程开发不能不懂的世界协调时UTC的由来

在各种时间标准出现之前&#xff0c;各地都是根据太阳来进行计时的。把太阳连续2次经过地球同一位置所经历的时间间隔称为真太阳日&#xff0c;然后再把这个太阳日划分为更小的时间单位&#xff0c;例如中国古代使用日晷记录时间&#xff0c;把一个太阳日分为12个时辰。因为地球…

海康+libtorch的血泪教训

一、LibTorch使用&#xff0c; 详见&#xff1a; /INCLUDE:?warp_sizecudaatYAHXZ 二、海康二次开发&#xff0c; 目前选4.31&#xff0c;只能c14。 三、做dll注意&#xff1a;

【MongoDB】分布式数据库入门级学习

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;为祖国的科技进步添砖Java 个性签名&#xff1a;保留赤子之心也许是种幸运吧 本文封面由 凯楠&#x1f4f8;友情提供 凯楠&#x1f4f8; - 不夜长安 目录 MongoDB 相关 数据库排行榜单 MongoDB 中文官网 菜鸟…

[Open-source tool]Uptime-kuma的簡介和安裝於Ubuntu 22.04系統

[Uptime Kuma]How to Monitor Mqtt Broker and Send Status to Line Notify Uptime-kuma 是一個基於Node.js的開軟軟體&#xff0c;同時也是一套應用於網路監控的開源軟體&#xff0c;其利用瀏覽器呈現直觀的使用者介面&#xff0c;如圖一所示&#xff0c;其讓使用者可監控各種…

【探索Linux】P.35(传输层 —— UDP协议)

阅读导航 引言一、UDP协议端格式二、UDP的特点三、UDP的缓冲区四、基于UDP的应用层协议温馨提示 引言 在上一篇文章中&#xff0c;我们深入探讨了网络协议的应用层&#xff0c;揭示了各种协议如何协同工作以确保信息在网络中正确、高效地传递。从HTTP到FTP&#xff0c;每一层协…

【分布式计算框架 MapReduce】MapReduce 初级编程

目录 一、MapReduce 示例程序的导入并运行测试 二、准备 4 个小文件&#xff08;文件大小分别为 1.7M&#xff0c;5.1M&#xff0c;3.4M&#xff0c;6.8M&#xff09; 1. 第一种情况&#xff0c;默认分片&#xff1a;不修改程序代码&#xff0c;直接使用 WordCount 源程序 2…

火了10年的电脑监控软件有哪些?盘点8款热门的电脑监控软件

电脑监控软件领域经历了多年的发展&#xff0c;一些软件因为其稳定的功能、良好的用户体验和不断更新的技术支持&#xff0c;得以在市场上保持长期的热度和用户基础。以下是几款在过去十年里广受好评且持续流行的内网监控软件&#xff1a; 1.安企神&#xff1a;由河北安企神网络…

c++ 子类继承父类

这个是子类继承父类 是否重写从父类那里继承来的函数 这个例子的路径 E盘 demo文件夹 fatherChildfunc

【C++ | 委托构造函数】委托构造函数 详解 及 例子源码

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

周边美食小程序系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;美食店铺管理&#xff0c;菜品分类管理&#xff0c;标签管理&#xff0c;菜品信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;美食店铺&#…

Python 面试【★★★】

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

springboot实习管理系统的设计与实现 LW +PPT+源码+讲解

第三章系统分析与设计 3.1 可行性分析 一个完整的系统&#xff0c;可行性分析是必须要有的&#xff0c;因为他关系到系统生存问题&#xff0c;对开发的意义进行分析&#xff0c;能否通过本系统来补充线下实习管理模式中的缺陷&#xff0c;去解决其中的不足等&#xff0c;通过对…

Java基础(五)——ArrayList

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

蓝卓出席“2024C?O大会”,探讨智能工厂建设新路径

6月29日&#xff0c;“2024C?O大会”在金华成功举办。此次大会由浙江省企业信息化促进会主办&#xff0c;与以往CIO峰会不同&#xff0c;“C?O”代表了企业数字化中的核心决策者群体&#xff0c;包括传统的CIO、CEO、CDO等。 本次大会围绕C?O、AIGC与制造业、数据价值、未来…

[NSSCTF]-Reverse:[SWPUCTF 2021 新生赛]easyapp(安卓逆向,异或)

无壳 把后缀名改为zip&#xff0c;找到apk 查看jadx 这里调用了MainActivity的lambda$onCreate$0$MainActivity&#xff0c;然后又调用了Encoder进行异或。 exp&#xff1a; result棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌 key987654321 flag for i in range(len(result)):flagchr(…

算法:链表题目练习

目录 链表的技巧和操作总结 常用技巧&#xff1a; 链表中的常用操作 题目一&#xff1a;反转一个单链表 题目二&#xff1a;链表的中间结点 题目三&#xff1a;返回倒数第k个结点 题目四&#xff1a;合并两个有序链表 题目五&#xff1a;移除链表元素 题目六&#xff…

Flutter TIM 项目实现

目录 1. 服务端API 1.1 生成签名 1.1.1 步骤 第一步:获取签名算法 第二步:查看函数输入输出 第三步:nodejs 实现功能 1.1.2 验证签名 小结 1.2 Rest API 调用 1.2.1 签名介绍 1.2.2 腾讯接口 生成管理员 administrator 签名 包装一个 post 请求函数 查询账号 …