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

串联所有单词的子串

  • 题目
    • 题目描述
    • 示例 1:
    • 示例 2:
    • 示例 3:
    • 提示:
    • 题目链接
  • 题解
    • 解题思路
    • python实现
    • 代码解释:
    • 提交结果

题目

题目描述

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

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

例如,如果 words = [“ab”,“cd”,“ef”], 那么 “abcdef”, “abefcd”,“cdabef”, “cdefab”,“efabcd”, 和 “efcdab” 都是串联子串。 “acdbef” 不是串联子串,因为他不是任何 words 排列的连接。
返回所有串联子串在 s 中的开始索引。你可以以 任意顺序 返回答案。

示例 1:

输入: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] 也是可以的。

示例 2:

输入:s = “wordgoodgoodgoodbestword”, words = [“word”,“good”,“best”,“word”]
输出:[]
解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。
s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。
所以我们返回一个空数组。

示例 3:

输入: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.length <= 104
1 <= words.length <= 5000
1 <= words[i].length <= 30
words[i] 和 s 由小写英文字母组成

题目链接

串联所有单词的子串

题解

解题思路

为了解决这个问题,我们可以使用滑动窗口和哈希表相结合的方法。基本思路是:

  1. 计算单词长度和总长度:首先计算每个单词的长度 word_len 和所有单词串联起来的总长度 total_len
  2. 创建一个计数器:使用 Counter 来统计 words 中每个单词出现的次数。
  3. 遍历字符串 s:使用滑动窗口的方式遍历字符串 s,检查每个可能的起始位置是否可以形成一个有效的串联子串。

具体步骤如下:

  • 对于每个起始位置,我们尝试构建一个与 words 总长度相等的子串,并检查这个子串中的单词是否符合 words 的计数要求。
  • 如果找到了一个匹配的子串,则记录下它的起始索引。
  • 为了避免重复计算,当窗口大小超过 total_len 时,移除最左边的单词并继续检查。

python实现

下面是 Python 实现代码:

from collections import Counter, defaultdict

def findSubstring(s: str, words: list) -> list:
    if not s or not words:
        return []

    word_len = len(words[0])
    total_len = len(words) * word_len
    word_count = Counter(words)
    result_indices = []

    # Iterate over possible starting offsets
    for offset in range(word_len):
        window_counter = Counter()
        start = offset
        count = 0
        
        for i in range(offset, len(s) - word_len + 1, word_len):
            word = s[i:i + word_len]
            
            if word in word_count:
                window_counter[word] += 1
                count += 1
                
                while window_counter[word] > word_count[word]:
                    left_word = s[start:start + word_len]
                    window_counter[left_word] -= 1
                    start += word_len
                    count -= 1
                
                if count == len(words):
                    result_indices.append(start)
                    # Move the window forward by one word to look for next match
                    left_word = s[start:start + word_len]
                    window_counter[left_word] -= 1
                    start += word_len
                    count -= 1
            else:
                # Reset the window if a word is not in words
                window_counter.clear()
                start = i + word_len
                count = 0
    
    return result_indices

代码解释:

  • 滑动窗口:我们使用了一个宽度为 total_len 的滑动窗口来遍历字符串 s。每次移动一个单词长度(word_len),并更新窗口内的单词计数。
  • Counter:用来追踪当前窗口内各个单词的数量,确保它们不超过 words 中的数量。
  • Offset 循环:由于单词长度固定,我们只需要对每个可能的起始偏移量(从 0word_len - 1)执行一次完整的扫描即可覆盖所有情况。
  • 边界条件处理:当遇到不在 words 中的单词时,重置窗口;当窗口内某个单词数量过多时,也相应调整窗口左边界以保持合法性。

这种方法有效地避免了暴力搜索带来的高时间复杂度问题,同时保证了正确性和较高的效率。

提交结果

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode】498.对角线遍历

无论何时何地&#xff0c;我都认为对于一道编程题&#xff0c;思考解法的时间用于是实际动手解决问题的2倍&#xff01;如果敲键盘编码需要5min&#xff0c;那么思考解法的过程至少就需要10分钟。 1. 题目 2. 思想 其实这就是一道模拟题&#xff0c;难度中等。做这种题的关键就…

uniapp中父组件传参到子组件页面渲染不生效问题处理实战记录

上篇文件介绍了,父组件数据更新正常但是页面渲染不生效的问题,详情可以看下:uniapp中父组件数组更新后与页面渲染数组不一致实战记录 本文在此基础上由于新增需求衍生出新的问题.本文只记录一下解决思路. 下面说下新增需求方便理解场景: 商品信息设置中添加抽奖概率设置…

Flutter提示错误:无效的源发行版17

错误描述 Flutter从3.10.1 升级到3.19.4&#xff0c;在3.10.1的时候一切运行正常&#xff0c;但是当我将Flutter版本升级到3.19.4后&#xff0c;出现了下方的错误 FAILURE: Build failed with an exception.* What went wrong: Execution failed for task :device_info_plus:…

etcd的dbsize引起的集群故障

故障现象 k8s集群不能访问&#xff0c;具体表现kubectl命令不能使用。 思路 检查apiserver服务状态&#xff0c;检查etcd集群状态中errors列中存在一个alarm:NOSPACE的告警 解决&分析 具体表现 恢复使用第一&#xff0c;先尝试解除告警看能否恢复 etcdctl --endpoin…

Redis性能优化18招

Redis性能优化的18招 目录 前言选择合适的数据结构避免使用过大的key和value[使用Redis Pipeline](#使用Redis Pipeline)控制连接数量合理使用过期策略使用Redis集群充分利用内存优化使用Lua脚本监控与调优避免热点key使用压缩使用Geo位置功能控制数据的持久化尽量减少事务使…

Docker 安装 Yapi

Docker 安装系列 Docker已安装。 1、场景Yapi使用的MongoDB用户信息 1.1 创建自定义 Docker 网络 首先&#xff0c;创建一个自定义的 Docker 网络&#xff0c;以便 MongoDB 和 YApi 容器可以相互通信 [rootflexusx-328569 data]# docker network create yapi-networ…

深度学习(2)前向传播与反向传播

这一次我们重点讲解前向传播与反向传播&#xff0c;对这里还是有点糊涂 前向传播&#xff08;Forward Propagation&#xff09;和反向传播&#xff08;Backward Propagation&#xff09;是深度学习中神经网络训练的核心过程。它们分别负责计算神经网络的输出以及更新神经网络的…

Mock神器:Easy-Mock 私有化部署及使用介绍

在现代前后端分离的开发模式中&#xff0c;后端接口的数据模拟是一个常见且必要的需求。尤其是在后端接口尚未开发完成时&#xff0c;前端开发需要依赖模拟数据进行开发与测试。Easy-Mock 是一个非常流行的开源工具&#xff08;虽然它已经停止更新好长时间了&#xff09;&#…

个人IP建设:简易指南

许多个体创业者面临的一个关键挑战是如何为其企业创造稳定的需求。 作为个体创业者&#xff0c;您无法使用营销团队&#xff0c;因此许多人通过推荐和他们的网络来产生需求。因此&#xff0c;扩大您的网络是发展您的业务和产生持续需求的最佳策略。 这就是个人IP和品牌发挥作…

二一(GIT4)、echarts(地图)、黑马就业数据平台(学生页-增 删 改)

1. echarts 地图 echarts社区&#xff1a;makeapie echarts社区图表可视化案例 社区模板代码地址&#xff1a;自定义 tooltip-轮播 - category-work,series-map地图,tooltip提示框,visualMap视觉映射 - makeapie echarts社区图表可视化案例 // todo: 籍贯分布 地图 function…

iPhone 17 Air基本确认,3个大动作

近段时间&#xff0c;果粉圈都在讨论一个尚未发布的新品&#xff1a;iPhone 17 Air&#xff0c;苹果又要来整新活了。 从供应链消息来看&#xff0c;iPhone 17 Air本质上是Plus的替代品&#xff0c;主要是在维持“大屏”这一卖点的同时&#xff0c;增加了“轻薄”属性&#xff…

数据结构之初始二叉树(1)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;数据结构&#xff08;Java版&#xff09; 目录 树型结构 树的概念 与树的有关概念 树的表示形式 树的应用 二叉树 概念 两种特殊的…

RabbitMQ七种工作模式之 RPC通信模式, 发布确认模式

文章目录 六. RPC(RPC通信模式)客户端服务端 七. Publisher Confirms(发布确认模式)1. Publishing Messages Individually(单独确认)2. Publishing Messages in Batches(批量确认)3. Handling Publisher Confirms Asynchronously(异步确认) 六. RPC(RPC通信模式) 客⼾端发送消息…

深入理解 SQL 注入:原理、攻击流程与防御措施

深入理解 SQL 注入&#xff1a;原理、攻击流程与防御措施 在当今数字化的时代&#xff0c;数据安全已成为每个企业和开发者必须面对的重要课题。SQL 注入&#xff08;SQL Injection&#xff09;作为一种常见的网络攻击方式&#xff0c;给无数企业带来了巨大的损失。本文将深入…

【项目实战】基于python+爬虫的电影数据分析及可视化系统

注意&#xff1a;该项目只展示部分功能&#xff0c;如需了解&#xff0c;文末咨询即可。 本文目录 1.开发环境2 系统设计 2.1 设计背景2.2 设计内容 3 系统页面展示 3.1 用户页面3.2 后台页面3.3 功能展示视频 4 更多推荐5 部分功能代码 5.1 爬虫代码5.2 电影信息代码 1.开发环…

JCR一区牛顿-拉夫逊优化算法+分解对比!VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测

JCR一区牛顿-拉夫逊优化算法分解对比&#xff01;VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测 目录 JCR一区牛顿-拉夫逊优化算法分解对比&#xff01;VMD-NRBO-Transformer-BiLSTM多变量时序光伏功率预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.中科院…

深入探索 Compose 渲染流程:从 UI 树到 Skia 绘制的实现解析

文章目录 前言Compose 渲染流程概述1. Compose 解析1.1 Compose 声明性 UI1.2 Compose 编译1.2.1 Compose 编译概述1.2.2 代码示例1.2.3 编译过程细节 1.3 组合与重组合1.3.1 组合&#xff08;Composition&#xff09;1.3.2 重组合1.3.3 组合与重组合的区别1.3.4 组合与重组合的…

数据结构排序算法详解

数据结构排序算法详解 1、冒泡排序&#xff08;Bubble Sort&#xff09;2、选择排序&#xff08;Selection Sort&#xff09;2、插入排序&#xff08;Insertion Sort&#xff09;4、快速排序&#xff08;Quick Sort&#xff09; 1、冒泡排序&#xff08;Bubble Sort&#xff09…

命令模式的理解和实践

在软件开发中&#xff0c;设计模式是开发者们经过长期实践总结出来的、可复用的解决方案&#xff0c;用于解决常见的设计问题。命令模式&#xff08;Command Pattern&#xff09;是行为型设计模式之一&#xff0c;它通过将一个请求封装成一个对象&#xff0c;从而允许用户用不同…

【C++】关系操作符的全面解析与高级应用

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;关系操作符1.关系操作符的分类与语义2.关系操作符的连用问题3.浮点数比较的精度问题问题示例解决方案 &#x1f4af;总结核心要点 &#x1f4af;小结 &#x1f4af;前言 在…