【刷题记录】30. 串联所有单词的子串

简介: 【刷题记录】30. 串联所有单词的子串

一、题目描述


来源:力扣(LeetCode)


给定一个字符串 s 和一些 长度相同 的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。


注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。


示例 1:


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

输出:[0,9]

解释:

从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。

输出的顺序不重要, [9,0] 也是有效答案。


示例 2:


输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]

输出:[]


示例 3:


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

输出:[6,9,12]


提示:


  • 1 <= s.length <= 104
  • s 由小写英文字母组成
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 30
  • words[i] 由小写英文字母组成


二丶思路分析


哈希表 + 滑动窗口实现


【刷题记录】3. 无重复字符的最长子串中我们时候滑动窗口来实现过寻找最长子串。


假设


  • 字符串 s的长度为 length
  • words中的单词个数为 m,每个单词长度为 n
  • 我们保持一个长度为 m*n 的窗口在字符串s上进行滑动,每次滑动的步长为 n(因为每个单词的长度是相同的,这样,每次滑动便不用重新计算窗口内的单词,因为每次窗口滑动的步长为 n,直接跨过了整个单词
  • 使用哈希表 map 记录 words 中每个单词的出现次数
  • 使用哈希表 cur统计窗口内子串 sub 每个单词的出现次数(每隔 n 长度作为一个单词)
  • 移动窗口,如果这个窗口内一旦出现不存在map中的单词,或者这个单词在子串中出现的次数已经等于map中的次数这个滑动窗口就不符合要求,直接进入下一个滑动窗口的匹配
  • 如果完全匹配上,则把滑动窗口的起始索引加入结果res中


三、代码实现

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        Map<String, Integer> map = new HashMap<>();
        // 统计 words 中「每个目标单词」的出现次数
for(String word : words){
            map.put(word, map.getOrDefault(word, 0) +1);
        }
        int length = s.length();
        int m = words.length;
        int n = words[0].length();
        List<Integer> res = new ArrayList<>();
for(int i =0; i < length - m * n +1; i++){
            Map<String, Integer> cur = new HashMap<>();
            int index = i;
while(index < i + m * n){
                String curWord = s.substring(index, index + n);
if(!map.containsKey(curWord) || cur.get(curWord) == map.get(curWord)){
                    break;
                }
                cur.put(curWord, cur.getOrDefault(curWord, 0) +1);
                index += n;
            }
if(index == i + m * n){
                res.add(i);
            }
        }
        return res;
    }
}

复杂度分析


  • 时间复杂度:
    网络异常,图片无法展示
    |
    n为字符串长度,m为单词个数
  • 空间复杂度:
    网络异常,图片无法展示
    |


运行结果


网络异常,图片无法展示
|


总结


这道题目也是算利用滑动窗口思想来解决的题型中的一种。


在这个基础上我们来记录对比目标的work和窗口内的,看是否能够满足我们要求


继续加油~~

目录
相关文章
|
Java
Java基础—笔记—继承篇
该内容介绍了Java中的继承概念。继承允许子类从父类继承属性和方法,简化代码并提高复用性。格式是`public class 子类 extends 父类`。特点包括子类能访问非私有数据,方法可以被重写(@Override标记),但私有和静态方法不能重写。权限修饰符有private、缺省、protected和public。Java支持单继承和多层继承,所有类间接继承自Object类。继承后,成员访问遵循就近原则,this指代本类,super指代父类。子类构造器默认调用父类无参构造器,也可通过super调用有参构造器。
88 0
Anaconda在开始菜单找不到Anaconda command prompt入口
这篇文章提供了解决Anaconda安装后在开始菜单找不到Anaconda command prompt入口问题的步骤,通过运行命令`python .\\Lib\_nsis.py mkmenus`重新创建Anaconda的开始菜单快捷方式。
Anaconda在开始菜单找不到Anaconda command prompt入口
|
Java 开发工具
IDEA中配置阅读并编辑jdk8源码的环境
IDEA中配置阅读并编辑jdk8源码的环境前言
IDEA中配置阅读并编辑jdk8源码的环境
|
人工智能 API 开发工具
「寻找热爱技术创作的你:写下你在技术探中的实践和思考」 零一万物大模型开放平台 第二天零一万物大模型开放平台 第二天 我爱我园
零一万物大模型开放平台支持OpenAI SDK,适配Python 3.7.1+。在解决Python版本不兼容问题(需用Python 3.8.10+)后,安装`openai` SDK,接着配置API基址和密钥,初始化客户端。成功调用`ChatCompletion.create`创建聊天完成例程,输出与预期一致。实现前需在平台注册并验证用户信息,获取API Key。
|
小程序 JavaScript 开发工具
【小程序项目开发-- 京东商城】uni-app之分类导航区域
【小程序项目开发-- 京东商城】uni-app之分类导航区域
【小程序项目开发-- 京东商城】uni-app之分类导航区域
|
JavaScript 安全 API
vue3注册添加全局实例属性的方法,如何在setup函数中调用
vue3注册添加全局实例属性的方法,如何在setup函数中调用
1443 2
|
存储 Java 程序员
Java从入门到精通:1.2.1选择一本合适的入门书籍
Java从入门到精通:1.2.1选择一本合适的入门书籍
105 1
|
C语言 Windows
全网最详细用c语言实现植物大战僵尸游戏(下)-2
全网最详细用c语言实现植物大战僵尸游戏(下)
342 0
|
Ruby Python
为 Jupyter Notebook 设置 Ruby Kernel
为 Jupyter Notebook 设置 Ruby Kernel
为 Jupyter Notebook 设置 Ruby Kernel
|
XML 存储 Java
Kotlin 进阶 | 不变型、协变、逆变
Kotlin 进阶 | 不变型、协变、逆变
10988 1