LeetCode每日一题——30. 串联所有单词的子串

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

题目

给定一个字符串 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] 由小写英文字母组成

思路

该题意思是求给定s中能被words中所有字符使用一次可以组成子串的起点下标。

因为words中字符长度一致,所以想到可以使用滑动窗口,窗口长度为words中字符的长度n。

并且需要一个哈希表记录words中的字符及出现的次数,因为words中的字符可能出现重复,不能简单使用数组判断是否存在。

具体方法是,维持这个滑动窗口,判断窗口中的值是否在words中

  • 如果不在,直接左右两端同时+1,窗口整体向右移动一个单位。
  • 如果在,哈希表中对应字符的数量-1,滑动窗口一次向右移动n个单位,直接判断下一个窗口中的字符是否在哈希表中,如果在循环上面步骤,注意:这里最多判断words中的字符长度即可,因为题目要求所有字符都出现且出现一次

最后判断哈希表中所有的值是否为零即可,若全为零记录这个滑动窗口左指针,若不为零直接左右两端同时+1,窗口整体向右移动,循环以上步骤即可。

题解

class Solution:
    def findSubstring(self, s: str, words: List[str]) -> List[int]:
        n = len(words[0])
        #  滑动窗口两侧指针
        l, r = 0, n
        res = []
        temp = {}
        # 哈希表记录字符及数量
        for i in words:
            temp[i] = temp.get(i, 0) + 1
        while r <= len(s):
            ans = copy.copy(temp)
          # 窗口中字符存在于words
            if s[l:r] in words:
              # 每次移动n个单位判断
                for i in range(0, len(words)):
                    index = s[l+i*n:r+i*n]
                    if ans.get(index, 0) != 0:
                        ans[index] -= 1
                    else:
                        break
            if len(set(ans.values())) == 1 and list(ans.values())[0]==0:
                res.append(l)
            # 窗口整体向右移动
            l += 1
            r += 1
        return res


目录
打赏
0
0
0
0
3
分享
相关文章
|
5月前
Leetcode(最后一个单词长度)
这篇文章介绍了两种解决LeetCode第58题的方法,即计算给定字符串中最后一个单词的长度,方法包括翻转字符串和逆向遍历统计。
37 0
|
5月前
【LeetCode 20】151.反转字符串里的单词
【LeetCode 20】151.反转字符串里的单词
40 0
LeetCode第58题最后一个单词的长度
LeetCode第58题"最后一个单词的长度"的解题方法,通过从字符串末尾向前遍历并计数非空格字符,直接得出最后一个单词的长度。
LeetCode第58题最后一个单词的长度
【Leetcode刷题Python】79. 单词搜索和剑指 Offer 12. 矩阵中的路径
Leetcode第79题"单词搜索"的Python解决方案,使用回溯算法在给定的二维字符网格中搜索单词,判断单词是否存在于网格中。
98 4
|
7月前
|
【Leetcode刷题Python】生词本单词整理
文章提供了一个Python程序,用于帮助用户整理和排版生词本上的单词,包括去除重复单词、按字典序排序,并按照特定的格式要求进行打印排版。
63 3
|
7月前
|
【Leetcode刷题Python】318. 最大单词长度乘积
本文提供了LeetCode题目318的Python编程解决方案,题目要求在一个字符串数组中找出两个不含有公共字母的单词,且这两个单词的长度乘积最大,如果不存在这样的两个单词,则返回0。
37 0
力扣经典150题第三十三题:最小覆盖子串
力扣经典150题第三十三题:最小覆盖子串
83 1
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
7月前
|
【Leetcode刷题Python】剑指 Offer 32 - III. 从上到下打印二叉树 III
本文介绍了两种Python实现方法,用于按照之字形顺序打印二叉树的层次遍历结果,实现了在奇数层正序、偶数层反序打印节点的功能。
83 6
【Leetcode刷题Python】牛客. 数组中未出现的最小正整数
本文介绍了牛客网题目"数组中未出现的最小正整数"的解法,提供了一种满足O(n)时间复杂度和O(1)空间复杂度要求的原地排序算法,并给出了Python实现代码。
168 2