2.7 滑动窗口专题:串联所有单词的子串

news2025/3/17 12:43:10

LeetCode 30. 串联所有单词的子串算法对比分析


1. 题目链接

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


2. 题目描述

给定一个字符串 s 和一个字符串数组 wordswords 中所有单词长度相同。要求找到 s 中所有起始索引,使得从该位置开始的连续子串包含 words 中所有单词的某种排列(不限制顺序)。
示例
输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9](子串 "barfoo""foobar" 符合条件)。


3. 算法思路

滑动窗口法

  1. 问题转化:将 words 的排列匹配问题转化为固定窗口长度的滑动窗口问题。
  2. 哈希表统计:用 hash1 记录 words 中单词的出现次数,hash2 记录当前窗口内单词的出现次数。
  3. 多起点遍历:由于单词长度固定为 nwSub,需遍历 nwSub 种可能的起始偏移(0 ≤ i < nwSub)。
  4. 窗口动态调整
    • 右指针扩展:每次截取一个单词加入窗口,更新哈希表。
    • 左指针收缩:当窗口内单词数量超过 nw 时,移动左指针。
  5. 结果判断:当窗口内单词数量等于 nw 且所有单词频率匹配时,记录起始索引。

暴力枚举法

  1. 遍历所有子串:枚举所有长度为 nw * nwSub 的子串。
  2. 分割统计:将子串分割为 nw 个单词,统计频率是否与 words 一致。

4. 示例分析

输入:s = "barfoothefoobarman", words = ["foo","bar"]

  1. 暴力枚举法

    • 枚举所有长度为 6 的子串,例如 "barfoo", "arfoot", "rfooth" 等。
    • 对每个子串分割为 ["bar","foo"]["arf","oot"],检查是否与 words 匹配。
  2. 滑动窗口法

    • i=0 时,窗口从 left=0 开始,截取 "bar""foo"count=2,记录索引 0。
    • i=9 时,窗口从 left=9 开始,截取 "foo""bar"count=2,记录索引 9。

5. 边界条件与注意事项
  1. 单词长度相同words 中所有单词长度必须一致。
  2. 空输入处理:若 words 为空或 s 长度不足,直接返回空。
  3. 哈希表更新:需在收缩窗口时及时减少 hash2 的计数,避免无效单词干扰。

6. 代码实现
class Solution 
{
public:
    vector<int> findSubstring(string s, vector<string>& words) 
    {
        vector<int> ret;
        int ns = s.size(), nw = words.size(), nwSub = words[0].size();
        if (ns < nwSub * nw) return ret;

        unordered_map<string, int> hash1;
        for (auto& word : words) hash1[word]++;

        for (int i = 0; i < nwSub; i++) 
        { // 遍历所有可能的起始偏移
            unordered_map<string, int> hash2;
            int left = i, count = 0; // left为窗口左边界
            for (int right = i; right + nwSub <= ns; right += nwSub) 
            {
                // 截取当前单词
                string in = s.substr(right, nwSub);
                hash2[in]++;
                // 更新有效计数:仅在当前单词属于hash1且未超过次数时增加count
                if (hash1.count(in) && hash2[in] <= hash1[in]) count++;

                // 当窗口内的单词数量超过nw时,收缩左边界
                while ((right - left) / nwSub + 1 > nw) 
                {
                    string out = s.substr(left, nwSub);
                    if (hash1.count(out) && hash2[out] <= hash1[out]) count--;
                    hash2[out]--;
                    left += nwSub; // 左指针移动一个单词长度
                }

                // 若有效计数等于nw,记录起始索引
                if (count == nw) ret.push_back(left);
            }
        }
        return ret;
    }
};

在这里插入图片描述


7.暴力枚举法与滑动窗口法对比图表
对比维度暴力枚举法滑动窗口法
核心思想枚举所有长度为 nw * nwSub 的子串,分割后比较单词频率。维护固定窗口长度,动态调整窗口内的单词频率。
时间复杂度O(ns * nw * nwSub)(每个子串需分割并统计频率)。O(ns * nwSub)(每个单词被处理一次)。
空间复杂度O(nw)(存储 words 的哈希表)。O(nw)(存储两个哈希表)。
实现方式双重循环遍历子串,内层循环分割并统计。单层循环扩展右指针,动态调整左指针。
适用场景小规模数据(ns ≤ 1e3, nw ≤ 10)。大规模数据(ns ≤ 1e5)。
优点逻辑简单,直接穷举所有可能性。时间复杂度低,适用于大规模数据。
缺点数据规模大时性能极差(例如 ns=1e4 时需 1e8 次操作)。需处理哈希表的动态更新和边界条件。

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

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

相关文章

电脑实用小工具--VMware常用功能简介

一、创建、编辑虚拟机 1.1 创建新的虚拟机 详见文章新创建虚拟机流程 1.2 编辑虚拟机 创建完成后&#xff0c;点击编辑虚拟机设置&#xff0c;可对虚拟机内存、处理器、硬盘等各再次进行编辑设置。 二、虚拟机开关机 2.1 打开虚拟机 虚拟机创建成功后&#xff0c;点击…

为训练大模型而努力-分享2W多张卡通头像的图片

最近我一直在研究AI大模型相关的内容&#xff0c;想着从现在开始慢慢收集各种各样的图片&#xff0c;万一以后需要训练大模型的时候可以用到&#xff0c;或者自己以后也许会需要。于是决定慢慢收集这些图片&#xff0c;为未来的学习和训练大模型做一些铺垫&#xff0c;哈哈。 …

JVM 垃圾回收器的选择

一&#xff1a;jvm性能指标吞吐量以及用户停顿时间解释。 二&#xff1a;垃圾回收器的选择。 三&#xff1a;垃圾回收器在jvm中的配置。 四&#xff1a;jvm中常用的gc算法。 一&#xff1a;jvm性能指标吞吐量以及用户停顿时间解释。 在 JVM 调优和垃圾回收器选择中&#xff0…

使用GPTQ量化Llama-3-8B大模型

使用GPTQ量化8B生成式语言模型 服务器配置&#xff1a;4*3090 描述&#xff1a;使用四张3090&#xff0c;分别进行单卡量化&#xff0c;多卡量化。并使用SGLang部署量化后的模型&#xff0c;使用GPTQ量化 原来的模型精度为FP16&#xff0c;量化为4bit 首先下载gptqmodel量化…

2025-03-16 学习记录--C/C++-PTA 习题4-2 求幂级数展开的部分和

合抱之木&#xff0c;生于毫末&#xff1b;九层之台&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; 一、题目描述 ⭐️ 习题4-2 求幂级数展开的部分和 已知函数e^x可以展开为幂级数1xx^2/2!x^3/3!⋯x^k/k!⋯。现给定一个实数x&a…

【C#】Http请求设置接收不安全的证书

在进行HTTP请求时&#xff0c;出现以下报错&#xff0c;可设置接收不安全证书跳过证书验证&#xff0c;建议仅测试环境设置&#xff0c;生产环境可能会造成系统漏洞 /// <summary> /// HttpGet请求方法 /// </summary> /// <param name"requestUrl"&…

AP AR

混淆矩阵 真实值正例真实值负例预测值正例TPFP预测值负例FNTN &#xff08;根据阈值预测&#xff09; P精确度计算&#xff1a;TP/(TPFP) R召回率计算&#xff1a;TP/(TPFN) AP 综合考虑P R 根据不同的阈值计算出不同的PR组合&#xff0c; 画出PR曲线&#xff0c;计算曲线…

Leetcode-1278.Palindrome Partitioning III [C++][Java]

目录 一、题目描述 二、解题思路 【C】 【Java】 Leetcode-1278.Palindrome Partitioning IIIhttps://leetcode.com/problems/palindrome-partitioning-iii/description/1278. 分割回文串 III - 力扣&#xff08;LeetCode&#xff09;1278. 分割回文串 III - 给你一个由小写…

C++特性——智能指针

为什么需要智能指针 对于定义的局部变量&#xff0c;当作用域结束之后&#xff0c;就会自动回收&#xff0c;这没有什么问题。 当时用new delete的时候&#xff0c;就是动态分配对象的时候&#xff0c;如果new了一个变量&#xff0c;但却没有delete&#xff0c;这会造成内存泄…

ctf web入门知识合集

文章目录 01做题思路02信息泄露及利用robots.txt.git文件泄露dirsearch ctfshow做题记录信息搜集web1web2web3web4web5web6web7web8SVN泄露与 Git泄露的区别web9web10 php的基础概念php的基础语法1. PHP 基本语法结构2. PHP 变量3.输出数据4.数组5.超全局变量6.文件操作 php的命…

MySQL-存储过程和自定义函数

存储过程 存储过程&#xff0c;一组预编译的 SQL 语句和流程控制语句&#xff0c;被命名并存储在数据库中。存储过程可以用来封装复杂的数据库操作逻辑&#xff0c;并在需要时进行调用。 使用存储过程 创建存储过程 create procedure 存储过程名() begin存储过程的逻辑代码&…

图——表示与遍历

图的两种主要表示方法 图有两种常用的表示方法&#xff0c;一种是邻接表法&#xff08;adjacency-list&#xff09;&#xff0c;另一种是邻接矩阵法&#xff08;adjacency-matrix&#xff09;。 邻接表法储存数据更紧凑&#xff0c;适合稀疏的图&#xff08;sparse graphs&am…

新手村:数据预处理-异常值检测方法

机器学习中异常值检测方法 一、前置条件 知识领域要求编程基础Python基础&#xff08;变量、循环、函数&#xff09;、Jupyter Notebook或PyCharm使用。统计学基础理解均值、中位数、标准差、四分位数、正态分布、Z-score等概念。机器学习基础熟悉监督/无监督学习、分类、聚类…

ChatGPT-4

第一章&#xff1a;ChatGPT-4的技术背景与核心架构 1.1 生成式AI的发展脉络 生成式人工智能&#xff08;Generative AI&#xff09;的演进历程可追溯至20世纪50年代的早期自然语言处理研究。从基于规则的ELIZA系统到统计语言模型&#xff0c;再到深度学习的革命性突破&#x…

C语言_数据结构总结9:树的基础知识介绍

1. 树的基本术语 - 祖先&#xff1a;考虑结点K&#xff0c;从根A到结点K的唯一路径上的所有其它结点&#xff0c;称为结点K的祖先。 - 子孙&#xff1a;结点B是结点K的祖先&#xff0c;结点K是B的子孙。结点B的子孙包括&#xff1a;E,F,K,L。 - 双亲&#xff1a;路径上…

Python学习第十八天

Django模型 定义&#xff1a;模型是 Django 中用于定义数据库结构的 Python 类。每个模型类对应数据库中的一张表&#xff0c;类的属性对应表的字段。 作用&#xff1a;通过模型&#xff0c;Django 可以将 Python 代码与数据库表结构关联起来&#xff0c;开发者无需直接编写 S…

蓝桥杯备考:图论之Prim算法

嗯。通过我们前面的学习&#xff0c;我们知道了&#xff0c;一个具有n个顶点的连通图&#xff0c;它的生成树包括n-1个边&#xff0c;如果边多一条就会变成图&#xff0c;少一条就不连通了 接下来我们来学一下把图变成生成树的一个算法 Prim算法&#xff0c;我们从任意一个结…

langchain框架

LangChain的架构分为多个层次&#xff0c;支持Python和JavaScript生态 基础层&#xff08;langchain-core&#xff09;&#xff1a;提供LLM抽象接口、表达式语言&#xff08;LCEL&#xff09;等核心机制&#xff0c;支持超过70种主流模型&#xff08;如GPT-4、Llama&#xff0…

RHCE(RHCSA复习:npm、dnf、源码安装实验)

七、软件管理 7.1 rpm 安装 7.1.1 挂载 [rootlocalhost ~]# ll /mnt total 0 drwxr-xr-x. 2 root root 6 Oct 27 21:32 hgfs[rootlocalhost ~]# mount /dev/sr0 /mnt #挂载 mount: /mnt: WARNING: source write-protected, mounted read-only. [rootlocalhost ~]# [rootlo…

Mybatis3 调用存储过程

1. 数据库MySQL&#xff0c;user表 CREATE TABLE user (USER_ID int NOT NULL AUTO_INCREMENT,USER_NAME varchar(100) NOT NULL COMMENT 用户姓名,AGE int NOT NULL COMMENT 年龄,CREATED_TIME datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,CREATED_BY varchar(100) NOT NUL…