LeetCode【0030】串联所有单词的子串

news2024/11/14 8:14:33

本文目录

  • 1 中文题目
  • 2 求解方法:滑动窗口
    • 2.1 方法思路
    • 2.2 Python代码
    • 2.3 复杂度分析
  • 3 题目总结

1 中文题目

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

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

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

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

示例:

输入: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] 也是可以的。
输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
输出:[]
解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。
s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。
所以返回一个空数组。
输入: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 . l e n g t h ≤ 1 0 4 1 \leq s.length \leq 10^4 1s.length104
  • 1 ≤ w o r d s . l e n g t h ≤ 5000 1 \leq words.length \leq 5000 1words.length5000
  • 1 ≤ w o r d s [ i ] . l e n g t h ≤ 30 1 \leq words[i].length \leq 30 1words[i].length30
  • words[i]s 由小写英文字母组成

2 求解方法:滑动窗口

2.1 方法思路

方法核心

使用滑动窗口和哈希表,按单词长度进行分组遍历,并动态维护当前窗口中的单词计数

实现步骤

(1)初始化:

  • 创建words中单词的频率字典
  • 计算关键参数(单词长度、单词数量等)

(2)滑动窗口:

  • 对每个可能的起始位置进行遍历
  • 维护当前窗口中的单词计数

(3)匹配过程:

  • 检查每个单词是否在目标词典中
  • 动态调整窗口大小
  • 记录有效的起始位置

方法示例

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

过程演示:
1. 初始化:
   word_len = 3
   word_count = 2
   word_dict = {"foo": 1, "bar": 1}

2. 第一轮遍历(i=0):
   检查: "bar" -> found
   检查: "foo" -> found, 添加索引0
   检查: "the" -> reset
   ...

3. 第二轮遍历(i=1)...

4. 第三轮遍历(i=2)...

返回:[0, 9]

2.2 Python代码

class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]:
        # 特殊情况处理
        if not s or not words:
            return []
            
        # 初始化结果列表
        result = []
        
        # 获取关键参数
        word_len = len(words[0])  # 每个单词的长度
        word_count = len(words)   # 单词的个数
        total_len = word_len * word_count  # 总长度
        s_len = len(s)  # 字符串长度
        
        # 如果字符串长度小于所需总长度,直接返回空列表
        if s_len < total_len:
            return []
            
        # 创建words中单词的计数字典
        word_dict = {}
        for word in words:
            word_dict[word] = word_dict.get(word, 0) + 1
            
        # 遍历所有可能的起始位置
        # 只需要遍历word_len个起始位置
        for i in range(word_len):
            # 初始化滑动窗口的左右边界
            left = i
            right = i
            
            # 当前窗口中的单词计数
            curr_dict = {}
            
            # 已匹配的单词数量
            count = 0
            
            # 右指针不超过字符串长度
            while right + word_len <= s_len:
                # 获取右侧单词
                word = s[right:right + word_len]
                right += word_len
                
                # 如果是目标单词
                if word in word_dict:
                    curr_dict[word] = curr_dict.get(word, 0) + 1
                    count += 1
                    
                    # 如果当前单词出现次数过多
                    while curr_dict[word] > word_dict[word]:
                        # 移除左侧单词直到符合要求
                        left_word = s[left:left + word_len]
                        curr_dict[left_word] -= 1
                        count -= 1
                        left += word_len
                        
                    # 如果找到所有单词
                    if count == word_count:
                        result.append(left)
                        # 移除最左侧的单词,继续寻找下一个匹配
                        left_word = s[left:left + word_len]
                        curr_dict[left_word] -= 1
                        count -= 1
                        left += word_len
                        
                else:
                    # 如果遇到非目标单词,重置窗口
                    left = right
                    curr_dict.clear()
                    count = 0
                    
        return result

2.3 复杂度分析

  • 时间复杂度:O(n * k),n是字符串长度,k是单个单词的长度
    • 实际上是O(n/k * k),因为每次移动k个字符
  • 空间复杂度:O(m)
    • m是words中不同单词的数量
    • 需要存储单词频率字典

3 题目总结

题目难度:困难
数据类型:字符串
数据结构:哈希表
应用算法:滑动窗口

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

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

相关文章

MyBatis从入门到进阶

目录 MyBatis入门1、创建项目、数据准备2、数据库配置3、编写持久层代码单元测试打印日志 基本操作查询数据插入数据删除数据更新数据 MyBatis - xml插入数据更新数据删除数据查询数据#{}与${}SQL注入排序like查询 MyBatis进阶if标签trim标签where标签set标签foreach标签sql标签…

【JavaWeb】JavaWeb入门之XML详解

目录 1.XML介绍 1.1.XML概述 1.1.1.什么是XML 1.1.2.XML的作用 1.1.3.XML与HTML的比较 1.1.4.XML和properties&#xff08;属性文件&#xff09;比较 1.1.5.W3C组织 1.2.XML语法概述 1.2.1.XML文档展示 1.2.2.XML文档的组成部分 1.3.XML文档声明 1.3.1.什么是XML文…

wordcloud库基本介绍

文章目录 wordcloud库概述wordcloud库的安装 wordcloud库使用说明配置对象参数 wordcloud应用实例实例: 政府工作报告词云 wordcloud库概述 wordcloud是优秀的词云展示第三方库 词云以词语为基本单位,更加直观和艺术地展示文本 wordcloud库的安装 (cmd命令行) pip install …

VMware和CentOS 7.6 Linux操作系统的安装使用

1. 安装VMware 安装VMware之前&#xff0c;有些电脑是需要去BIOS里修改设置开启cpu虚拟化设备支持才能安装。如果运气不好在安装过程中安装不了的话就自行百度吧。 打开 VMware 的官网: https://www.vmware.com/ 点击 product&#xff0c;往下滑找到 see desktop hypeerviso…

LLM在Transformer上的改动

LLM在Transformer上的改动 1.multi-head共享1.1BERT的逻辑1.2multi-head共享 2.attention的前后网络2.1传统Transformer&#xff1a;2.2GPTJ结构&#xff1a; 3.归一化层的位置&#xff08;LayerNorm&#xff09;4.归一化层函数的选择4.1LayerNorm4.2RMSNorm 3.激活函数4.LLama…

解决SpringBoot3的Validated依赖实现自定义注解失效问题

我们引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency> Validated实现自定义注解 我们首先看看自定义注解里面&#xff0c;用到的注解的包 我们…

当微软windows的记事本被AI加持

1985年&#xff0c;微软发布了Windows 1.0&#xff0c;推出了一款革命性的产品&#xff1a;记事本&#xff08;Notepad&#xff09;。这款软件旨在鼓励使用一种未来主义的新设备——鼠标&#xff0c;并让人们可以不依赖VI等键盘工具就能书写文本和编写代码。记事本因其简洁和高…

前端常用布局模板39套,纯CSS实现布局

前端常用布局模板39套&#xff0c;纯CSS实现布局 说明 写博客、官网、管理后台都可以参考以下布局模板&#xff0c;实现模板布局的方式包含&#xff1a;flex、CSS、HTML5、Layout。 不需要下载积分&#xff0c;没有特殊库引用&#xff0c;不用安装任何插件&#xff0c;打开资源…

微服务day07

Elasticsearch 需要安装elasticsearch和Kibana&#xff0c;应为Kibana中有一套控制台可以方便的进行操作。 安装elasticsearch 使用docker命令安装&#xff1a; docker run -d \ --name es \-e "ES_JAVA_OPTS-Xms512m -Xmx512m" \ //设置他的运行内存空间&#x…

java常用工具介绍

1. 集成开发环境&#xff08;IDE&#xff09;&#xff1a; • Eclipse&#xff1a;一个开放源代码的、基于Java的可扩展开发平台。它提供了一个框架和一组服务&#xff0c;用于通过插件组件构建开发环境。Eclipse 还包括用于Java开发的工具&#xff08;Java Development Tools,…

C++入门基础知识148—【关于C++ 二元运算符重载】

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///C爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于C 二元运算符重载的相关内容&#xff01…

黑马智数Day7

获取行车管理计费规则列表 封装接口 export function getRuleListAPI(params) {return request({url: parking/rule/list,params}) } 获取并渲染数据 import { getRuleListAPI } from /apis/carmounted() {this.getRuleList() }methods: {// 获取规则列表async getRuleList(…

NodeJS的安装 npm 配置和使用 Vue-cli安装 Vue项目介绍

一.前端工程化 前端工程化是使用软件工程的方法来单独解决前端的开发流程中模块化、组件化、规范化、自动化的问题,其主要目的为了提高效率和降低成本 1. NodeJS的安装 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环 境&#xff0c;可以使 JavaScript 运行在服务…

Anolis8.2系统中搭建python环境

文章目录 安装依赖项依赖项介绍 下载python源码包安装python源码包 安装依赖项 [rootPython ~]# dnf install -y gcc make zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel xz-devel libffi-devel uuid-devel libnsl2-d…

51c自动驾驶~合集10

我自己的原文哦~ https://blog.51cto.com/whaosoft/11638131 #端到端任务 说起端到端&#xff0c;每个从业者可能都觉得会是下一代自动驾驶量产方案绕不开的点&#xff01;特斯拉率先吹响了方案更新的号角&#xff0c;无论是完全端到端&#xff0c;还是专注于planner的模型&a…

基于Python+Django+Vue3+MySQL实现的前后端分类的商场车辆管理系统

项目名称&#xff1a;基于PythonDjangoVue3MySQL实现的前后端分离商场车辆管理系统 技术栈 开发工具&#xff1a;PyCharm、Visual Studio Code (VSCode)运行环境&#xff1a;Python 3.10、MySQL 8.0、Node.js 18技术框架&#xff1a;Django 5、Vue 3.4、Ant-Design-Vue 4.12 …

JAVA后端生成图片滑块验证码 springboot+js完整案例

前言 现在大部分网部都是图片滑块验证码&#xff0c;这个得要与后端联动起来才是确保接口安全性 通过我们系统在发送手机短息时都会选进行滑块验证&#xff0c;但是我们要保证发送短息接口的全安&#xff0c;具体路思如下 那么这个滑块的必须是与后端交互才能保证安全性&…

人工智能大比拼(3)

已知x-,y-6&#xff0c;且下述表达式的值与x的取值无关&#xff0c;求y -10x2y7xy 上述这个很简单的数学题&#xff0c;可是在各家AI之间出现了争议&#xff0c;本期我使用了四个AI&#xff1a;kimi&#xff0c;商量&#xff0c;文心一言&#xff0c;chatyy 先来看一下kimi的表…

SQLI LABS | Less-45 POST-Error Based-String-Stacked-Bilnd

关注这个靶场的其它相关笔记&#xff1a;SQLI LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;过关流程 输入下面的链接进入靶场&#xff08;如果你的地址和我不一样&#xff0c;按照你本地的环境来&#xff09;&#xff1a; http://localhost/sqli-labs/Less-45/ 本关是堆…

sol机器人pump机器人如何实现盈利的?什么是Pump 扫链机器人?

什么是Pump 扫链机器人&#xff0c;它的盈利逻辑优化策略是什么&#xff1f; Pump 扫链机器人&#xff0c;通过智能化、自动化的买卖操作帮助投资者实现快速盈利。在此基础上&#xff0c;我们对该机器人的盈利逻辑进行了深度优化&#xff0c;涵盖了买入策略和止盈策略的各个方面…