Leetcode 串联所有单词的子串

server/2024/12/22 17:21:53/

在这里插入图片描述

算法思想(中文解释)

这道题目要求我们在字符串 s 中找到所有子串,这些子串是字符串数组 words 中所有单词的串联,并且每个单词只能使用一次,且顺序可以任意。下面是代码的算法思想:


1. 核心思路

分解问题

  • 因为每个单词长度相同,我们可以使用一个滑动窗口(Sliding Window)来检查所有可能的子串。
  • 判断一个子串是否是所有单词的串联,可以通过比较单词的频次。

2. 步骤讲解

(1)初始化:
  • 单词长度:用 wordLength 表示 words 中每个单词的长度(因为题目保证它们长度相同)。
  • 总串联长度totalLength = wordLength * words.length,因为子串的长度一定是所有单词的长度之和。
  • 构造单词频次表:用 wordMap 记录 words 中每个单词的出现次数,便于后续比较。
(2)滑动窗口遍历:
  • 从字符串 s 的每个位置开始,以长度为 totalLength 的窗口进行检查:
    • 提取窗口中的子串 sub
    • 检查这个子串是否包含了 words 中所有单词且频次正确。
(3)子串验证:
  • 对于窗口中的子串 sub,将其按照 wordLength 分割成一个个小单词。
  • 检查这些小单词是否在 wordMap 中,并验证它们的出现频次是否超出限制:
    • 如果某个单词不在 wordMap 中,立即返回 false
    • 如果某个单词出现的次数超过了在 wordMap 中的次数,也返回 false
  • 如果所有单词验证通过,则说明当前窗口位置是符合要求的,记录下起始索引。

3. 时间复杂度分析

  1. 构造单词频次表O(m),其中 mwords 的长度(即单词个数)。
  2. 滑动窗口遍历:外层遍历最多需要 n - totalLength + 1 次,n 是字符串 s 的长度。
  3. 验证子串:每次验证需要遍历窗口中的所有单词,复杂度为 O(m * wordLength)

因此,总复杂度为
[ O((n - totalLength + 1) \cdot m \cdot wordLength) ]
通常可以简化为 O(n * m),适用于 s 较长和 words 较短的场景。


4. 代码逻辑解释

主函数:
  1. wordMap:统计 words 中每个单词的出现频次。
  2. 滑动窗口遍历:通过 for 循环,遍历从 0 到 s.length() - totalLength 的所有可能起始位置。
  3. 子串验证:调用辅助函数 isValid() 检查是否符合要求。
辅助函数 isValid
  1. 将子串 sub 分割成长度为 wordLength 的小单词。
  2. 使用 seen 哈希表记录窗口内每个单词的频次。
  3. wordMap 进行比较,判断是否匹配。

5. 关键优化点

  1. 滑动窗口:避免暴力检查所有子串,只检查可能的窗口,减少不必要的计算。
  2. 哈希表:使用 wordMapseen 快速判断频次关系,而不是逐一比较。
  3. 提前退出:在验证过程中,一旦发现不匹配的单词,立即退出验证,避免冗余计算。

6. 适用场景

算法非常适用于以下情况:

  • 单词长度固定,字符串较长。
  • words 中的单词个数适中(否则频次表的维护开销较大)。

通过滑动窗口和哈希表的结合,这个算法能够高效解决题目要求。

java solution

java">class Solution {public List<Integer> findSubstring(String s, String[] words) {List<Integer> result = new ArrayList<>();if(s == null || s.length() == 0 || words.length == 0 || words == null) return result;//初始化辅助变量int wordsLength = words.length;int wordLength = words[0].length();int totalLength = wordLength * wordsLength;//创建频率统计哈希表Map<String, Integer> freq = new HashMap<>();for(String word:words) {freq.put(word, freq.getOrDefault(word, 0) + 1);}//变量字符串sfor(int i = 0; i <= s.length() - totalLength; i++) {//首先获取窗口内的子串String sub = s.substring(i, i + totalLength); //substring 是左闭右开//然后验证此时窗口内的子串if(isValid(sub, freq, wordLength)) {result.add(i);}}return result;}private boolean isValid(String sub, Map<String, Integer> freq, int wordLength) {Map<String, Integer> seen = new HashMap<>(); //存储子串中的单词频次for(int j = 0; j < sub.length(); j += wordLength) {//提取子串中的单词String word = sub.substring(j, j + wordLength);if(!freq.containsKey(word)) { //如果这个单词不在freq频率表中,return false;}seen.put(word, seen.getOrDefault(word, 0) + 1); //更新seen中的频次if(seen.get(word) > freq.get(word)) { //如果频次超过freq的限制return false; }}return true;}
}

182 个测试用例通过了 181 个,被全 a 的测试用例卡住了(超时),


http://www.ppmy.cn/server/152279.html

相关文章

三、使用langchain搭建RAG:金融问答机器人--检索增强生成

经过前面2节数据准备后&#xff0c;现在来构建检索 加载向量数据库 from langchain.vectorstores import Chroma from langchain_huggingface import HuggingFaceEmbeddings import os# 定义 Embeddings embeddings HuggingFaceEmbeddings(model_name"m3e-base")#…

信息安全管理与评估赛题第4套

全国职业院校技能大赛 高等职业教育组 信息安全管理与评估 赛题四 模块一 网络平台搭建与设备安全防护 1 赛项时间 共计180分钟。 2 赛项信息 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第一阶段 网络平台搭建与设备安全防护 任务1 网络平台搭建 XX:XX- XX:XX 50 任务2…

视频点播系统|Java|SSM|VUE| 前后端分离

【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、Maven、Mysql5.7 4⃣️&#xff1a;技术栈&#xff1a;Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html 5⃣️数据库可…

uni-app开发商品分类页面实现

目录 一:功能概述 二:功能实现 一:功能概述 这里商品分类按照常规的分类页面样式设计,左侧为一级分类,右侧为二级分类。在左侧切换不同的一级分类可以修改右侧的二级分类数据。右侧的展现方式是最上面显示对应的一级分类logo图片,下面展示二级分类的logo和名称。 二:…

SpringBoot 3.4.x踩坑记录及解决方案(持续更新)

废话 最近使用JDK17Spring Boot3.4.0 做新项目遇到的一些坑&#xff0c;记录并且给出一些实际的解决方案 一、集成Mybatis Plus 3.5.9的问题 第一&#xff1a;不能只引入mybatis-plus-spring-boot3-starter依赖了&#xff0c;需要配合mybatis-plus-jsqlparser <dependenc…

实验13 C语言连接和操作MySQL数据库

一、安装MySQL 1、使用包管理器安装MySQL sudo apt update sudo apt install mysql-server2、启动MySQL服务&#xff1a; sudo systemctl start mysql3、检查MySQL服务状态&#xff1a; sudo systemctl status mysql二、安装MySQL开发库 sudo apt-get install libmysqlcli…

【MAC】深入浅出 Homebrew 下 Nginx 的安装与配置指南

硬件&#xff1a;Apple M4 Pro 16寸 系统&#xff1a; macos Sonoma 15.1.1 Nginx 是一款高性能的 Web 服务器和反向代理服务器&#xff0c;广泛应用于全球各地的网站和企业应用中。本文将详细介绍如何在 macOS 环境下使用 Homebrew 安装、启动、管理以及优化配置 Nginx&#x…

macOS brew安装

brew 可以用命令在mac上安装、卸载、更新各种软件包。它是一个用ruby写的软件&#xff0c;软件是托管在github上的。 1、安装brew&#xff0c;一般选择清华源&#xff0c;如果之前安装过brew&#xff0c;执行下面命令时会自动备份old_homebrew&#xff0c;按照操作执行即可&…