串联所有单词的子串

news2024/11/20 3:30:53

题目链接

串联所有单词的子串

题目描述


注意点

  • words[i] 和 s 由小写英文字母组成
  • 1 <= words.length <= 5000
  • 可以以 任意顺序 返回答案
  • words中所有字符串长度相同

解答思路

  • 根据滑动窗口+哈希表解决本题,哈希表存储words中所有的单词及单词的出现次数,滑动窗口时使用另一个哈希表存储当前窗口内已经出现的单词及单词的出现次数
  • 因为words中所有字符串长度相同,所以在移动滑动窗口右边界时应该以单词为维度,每次移动wordLen个单位,然后判断该部分单词rightWord是否能作为串联串联所有单词的子串的一部分,有以下三种情况:
    • 如果rightWord根本不属于words中的单词,说明包含该单词时的子串一定不满足题意,此时需要将滑动窗口直接移动到该单词右侧,也就是直接重置滑动窗口的左右边界
    • 如果rightWord属于words中的单词,但是当前滑动窗口中该单词数量已经达到words中该单词的最大数量,此时需要移动滑动窗口的左边界,移动时每次也同样移动wordLen个单位,直到左侧找到一个与rightWord相同的值leftWord(一定能找到),将滑动窗口左边界移动到leftWord右侧
    • 如果rightWord属于words中的单词,且当前滑动窗口中该单词数量还未超过words中该单词的最大数量,此时满足题意,继续移动滑动窗口右边界(注意判断该滑动窗口已经是串联所有单词的子串的情况)
  • 上述过程并未判断所有情况,因为每次移动边界时都是以wordLen为单位,如果从字符串首位置开始,可能会忽略1,2…(wordLen - 1)为起始位置的情况,观察规律可得,只需要对1,2…(wordLen - 1)为起始位置都执行一次上述的操作就可以考虑到所有的情况

代码

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res = new ArrayList<>();
        int wordSum = words.length;
        int wordLen = words[0].length();
        if (s.length() < wordSum * wordLen) {
            return res;
        }
        Map<String, Integer> map = new HashMap<>();
        for (String word : words) {
            map.put(word, map.getOrDefault(word, 0) + 1);
        }
        for (int i = 0; i < wordLen; i++) {
            int left = i;
            int right = i;
            int currWordSum = 0;
            Map<String, Integer> visitedMap = new HashMap<>();
            while (right + wordLen <= s.length()) {
                // 长度越界,剩下的子串一定无法串联所有单词
                if (left + (wordSum - currWordSum) * wordLen > s.length()) {
                    break;
                }
                String leftWord = s.substring(left, left + wordLen);
                String rightWord = s.substring(right, right + wordLen);
                // 该单词不存在,则有该单词的部分都一定不满足题意,将滑动窗口左边界移动至该单词右侧
                if (map.get(rightWord) == null) {
                    left = right + wordLen;
                    visitedMap = new HashMap<>();
                    currWordSum = 0;
                }
                // 该单词存在但words中已经没有该单词
                if (map.get(rightWord) != null && visitedMap.getOrDefault(rightWord, 0) >= map.get(rightWord)) {
                    while (left < right && !rightWord.equals(leftWord)) {
                        visitedMap.put(leftWord, visitedMap.get(leftWord) - 1);
                        left += wordLen;
                        leftWord = s.substring(left, left + wordLen);
                        currWordSum--;
                    }
                    left += wordLen;
                }
                // 该单词存在满足题意
                if (map.get(rightWord) != null && visitedMap.getOrDefault(rightWord, 0) < map.get(rightWord)) {
                    visitedMap.put(rightWord, visitedMap.getOrDefault(rightWord, 0) + 1);
                    currWordSum++;
                    // 已找到串联所有单词的子串
                    if (currWordSum == wordSum) {
                        res.add(left);
                        visitedMap.put(leftWord, visitedMap.get(leftWord) - 1);
                        currWordSum--;
                        left += wordLen;
                    }
                }
                right += wordLen;
            }
        }
        return res;
    }
}

关键点

  • 滑动窗口的思想
  • 移动滑动窗口时其对应的哈希表的变化
  • 移动滑动窗口右边界时对应单词是否是串联所有单词的子串的三种情况

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

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

相关文章

【mysql 数据库事务】开启事务操作数据库,写入失败后,不回滚,会有问题么? 这里隐藏着大坑,复试,面试时可以镇住面试老师!!!!

建表字段: CREATE TABLE user (id INT(11) NOT NULL AUTO_INCREMENT,nickname VARCHAR(32) NOT NULL COLLATE utf8mb4_general_ci,email VARCHAR(32) NOT NULL COLLATE utf8mb4_general_ci,status SMALLINT(6) UNSIGNED NULL DEFAULT NULL,password VARCHAR(256) NULL DEFAULT…

【Vue3】3-5 :组件内容的组合与分发

文章目录 前言问题本节内容 插槽 slot>> 使用>> 效果 (前后相同) 插槽的特性实战> 实例 1&#xff1a;【作用域】根组件中渲染> 效果> 原因>> 实例 2&#xff1a;【具名插槽】即多个插槽> 效果>> 实例 3&#xff1a;【作用域插槽】插槽能访…

kubectl 声明式资源管理方式

目录 介绍 YAML 语法格式 命令 应用yaml文件指定的资源 删除yaml文件指定的资源 查看资源的yaml格式信息 查看yaml文件字段说明 查看 api 资源版本标签 修改yaml文件指定的资源 离线修改 在线修改 编写yaml文件 创建资源对象 查看创建的pod资源 创建service服务对…

WordPress 插件存在漏洞,500 万网站面临严重安全风险

网络安全研究人员近期发现 WordPress LiteSpeed Cache 插件中存在一个安全漏洞&#xff0c;该漏洞被追踪为 CVE-2023-40000&#xff0c;未经身份验证的威胁攻击者可利用该漏洞获取超额权限。 LiteSpeed Cache 主要用于提高网站性能&#xff0c;据不完全统计已经有 500 多万安装…

K8s Pod资源管理组件

目录 Pod基础概念 在Kubrenetes集群中Pod有如下两种使用方式 pause容器使得Pod中的所有容器可以共享两种资源 网络 存储 总结 kubernetes中的pause容器主要为每个容器提供功能 Kubernetes设计这样的Pod概念和特殊组成结构的用意 通常把Pod分为以下几类 自主式Pod 控…

幻兽帕鲁(Palworld 1.4.11.5.0)私有服务器搭建(docker版)

文章目录 说明客户端安装服务器部署1Panel安装和配置docker服务初始化设置设置开机自启动设置镜像加速 游戏服务端部署游戏服务端参数可视化配置 Palworld连接服务器问题总结 服务端升级&#xff08;1.5.0&#xff09; 说明 服务器硬件要求&#xff1a;Linux系统/Window系统&a…

振动解调用的包络谱计算

1缘起 在振动分析中&#xff0c;对于一些高频频点的分析计算&#xff0c;使用包络谱技术&#xff0c;进而得到特化谱是最适宜的。 1.1 包络谱是什么样子的&#xff1f; 我们看matlab信号分析中提供的一个实例&#xff1a; https://www.mathworks.com/help/signal/ug/comput…

前端JS 时间复杂度和空间复杂度

时间复杂度 BigO 算法的时间复杂度通常用大 O 符号表述&#xff0c;定义为 T(n) O(f(n)) 实际就是计算当一个一个问题量级&#xff08;n&#xff09;增加的时候&#xff0c;时间T增加的一个趋势 T(n)&#xff1a;时间的复杂度&#xff0c;也就相当于所消耗的时长 O&#xff1…

纯国产轻量化数字孪生:智慧城市、智慧工厂、智慧校园、智慧社区。。。

AMRT 3D数字孪生引擎介绍 AMRT3D引擎是一款融合了眸瑞科技的AMRT格式与轻量化处理技术为基础&#xff0c;以降本增效为目标&#xff0c;支持多端发布的一站式纯国产自研的CS架构项目开发引擎。 引擎包括场景搭建、UI拼搭、零代码交互事件、光影特效组件、GIS/BIM组件、实时数据…

十四、综合项目(斗地主)

综合项目&#xff08;斗地主&#xff09; 1.准备牌、洗牌、发牌、看牌2.对每人手中的牌进行排序2.1 排序方法1&#xff08;利用序号进行排序&#xff09;2.2排序方法2&#xff08;给每一张牌计算价值&#xff09; 3.两个实体类3.1 User3.2 Poker 4.登录页面4.1 验证码代码4.2 登…

【蓝桥杯】快读|min和max值的设置|小明和完美序列|​顺子日期​|星期计算|山

目录 一、输入的三种方式 1.最常见的Scanner的输入方法 2.数据多的时候常用BufferedReader快读 3.较麻烦的StreamTokenizer快读&#xff08;用的不多&#xff09; StreamTokenizer常见错误&#xff1a; 二、min和max值的设置 三、妮妮的翻转游戏 四、小明和完美序列 五…

如何删除视频中不想要的部分?分享实用工具和步骤!

在数字化时代&#xff0c;视频已成为我们生活中不可或缺的一部分。无论是观看电影、记录生活&#xff0c;还是制作专业的广告、教学材料&#xff0c;我们都需要对视频进行编辑处理。其中&#xff0c;删除视频中不想要的部分是最常见的需求之一。那么&#xff0c;如何轻松实现这…

Pytorch添加自定义算子之(5)-配置GPU形式的简单add自定义算子

参考:https://zhuanlan.zhihu.com/p/358778742 一、头文件 命名为:add2.h void launch_add2(float *c,const float *a,const float *b,int n);

Jvm之内存泄漏

1 内存溢出 1.1 概念 java.lang.OutOfMemoryError&#xff0c;是指程序在申请内存时&#xff0c;没有足够的内存空间供其使用&#xff0c;出现OutOfMemoryError。产生该错误的原因主要包括&#xff1a;JVM内存过小。程序不严密&#xff0c;产生了过多的垃圾。 程序体现: 内…

Win UI3开发笔记(四)设置主题续

上文讲到过关于界面和标题栏以及普通文本的主题设置&#xff0c;这篇说一下关于对话框的主题设置。 我最终没找到办法&#xff0c;寻求办法的朋友可以不用接着看了&#xff0c;以下只是过程。 一个对话框包括标题部分、内容部分和按钮部分&#xff0c;其中&#xff0c;在Cont…

论文笔记:A survey on zero knowledge range proofs and applications

https://link.springer.com/article/10.1007/s42452-019-0989-z 描述了构建零知识区间证明&#xff08;ZKRP&#xff09;的不同策略&#xff0c;例如2001年Boudot提出的方案&#xff1b;2008年Camenisch等人提出的方案&#xff1b;以及2017年提出的Bulletproofs。 Introducti…

Python 全栈系列227 部署chatglm3-API接口

说明 上一篇介绍了基于算力租用的方式部署chatglm3, 见文章&#xff1b;本篇接着看如何使用API方式进行使用。 内容 1 官方接口 详情可见接口调用文档 调用有两种方式&#xff0c;SDK包和Http。一般来说&#xff0c;用SDK会省事一些。 以下是Python SDK包的git项目地址 安…

ChatGPT 正测试Android屏幕小组件;联想ThinkBook 推出透明笔记本电脑

▶ ChatGPT 测试屏幕小组件 近日 ChatGPT 正在测试 Android 平台上的屏幕小组件&#xff0c;类似于手机中的悬浮窗&#xff0c;按住 Android 手机主屏幕上的空白位置就可以调出 ChatGPT 的部件菜单。 菜单中提供了许多选项&#xff0c;包括文本、语音和视频查询的快捷方式&…

vue3的echarts从后端获取数据,用于绘制图表

场景需求&#xff1a;后端采用flask通过pymysql从数据库获取数据&#xff0c;并返回给前端。前端vue3利用axios获取数据并运用到echarts绘制图表。 第一步&#xff0c;vue中引入echarts 首先vue下载echarts npm install echarts 然后在main.js文件写如下代码 import {create…

【appium】App类型、页面元素|UiAutomator与appium|App元素定位

目录 一、App前端基础知识 1、App类型划分 2、App类型对比 3、App页面元素 App页面元素分为布局和控件两种 常见布局&#xff1a; 常见控件&#xff1a;定位软件&#xff1a;appium和sdk自带的uiautomatorviewer都可以定位 二、App元素定位 1、id定位 2、text定位 3…