# 【基础篇 - Day 23】 2020-11-23 - 30. 串联所有单词的子串

# 题目描述

# 入选理由

  1. hashtable 用于空间换时间

# 题目描述

给定一个字符串 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"]
输出:[]

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

# 我的回答

# 解法一

# 时空复杂度

时间复杂度:O(n*k) s.length * words.length

空间复杂度: O(n) 2 个 Map 的空间 N 最大为 words.length

今天的好难,一开始就想 用一个 wordLength 循环出来 然后条件删减把自己绕晕了,要循序渐进啊。

var findSubstring = function (s, words) {
    const wordLength = words[0].length
    const res = []
    let wordMap = new Map()
    for (let i = 0; i < words.length; i++) {
        const newVal = (wordMap.get(words[i]) || 0) + 1
        wordMap.set(words[i], newVal)
    }
    for (let i = 0; i < (s.length - wordLength + 1); i++) {
        let map = new Map()
        let num = 0
        while (num < words.length) {
            const word = s.substring(i + num * wordLength, i + (num + 1) * wordLength);
            if (words.includes(word)) {
                const newVal = (map.get(word) || 0) + 1
                map.set(word, newVal)
                if (newVal > wordMap.get(word)) {
                    break;
                }
            } else {
                break;
            }
            num++
        }
        if (num == words.length) res.push(i)
    }
    return res
};

# 参考回答

Last Updated: 12/22/2022, 9:53:26 AM