leetcode刷题记录-30. 串联所有单词的子串

104 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情

前言

今天的题目为困难,这道题需要掌握题目中的重点,所用到的知识点并不是特别难以理解的算法或者是很难的计算,只需要掌握特定的方法,可能过程会比简单中等题更复杂,但是理清楚逻辑,题目也会变得非常简单。

每日一题

今天的题目是 30. 串联所有单词的子串,难度为困难

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

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

 

示例 1:

输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:
从索引 09 开始的子串分别是 "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] 由小写英文字母组成

题解

哈希表+滑动窗口

题目的关键点在于,word 都是相同长度的,也就是说我们知道了其中一个word的长度,其他word的长度就也都能够知道。

并且单词的组成顺序是没有做出限制的,这样我们就能够想到,利用哈希表记录下每个单词出现的次数,然后在滑动窗口的时候,优先去判断当前这个单词是否存在哈希表当中,然后就是记录下这个单词在滑动窗口中出现的次数,两个哈希表中对应的出现次数也需要做出比较,一旦在滑动窗口中出现的次数更多,那么就也可以判断不相等。

并且在每次的成功比较之后,回去记录下当前经历过比较的字符串长度,一旦经过比较的字符串长度等于题目要求的word数组的总长,那么就说明,当前保存下来的子串能够由题目要求的数组拼凑而成。

function findSubstring(s: string, words: string[]): number[] {
    let wordsMap = new Map();
    for (let word of words) {
        wordsMap.set(word, (wordsMap.get(word) || 0)+ 1);  
    }
    let n: number = words[0].length;
    let m: number = n * words.length;
    let res: number[] = [];
    for (let i = 0; i < s.length - m + 1; i++) {
        let curWords: string = s.substring(i, i + m);
        let map = new Map();
        let curLength: number = 0;
        for (let j = 0; j < m; j += n) {
            let curWord: string = curWords.substring(j, j + n);
            map.set(curWord, (map.get(curWord) || 0) + 1);
            if (!wordsMap.has(curWord)) {
                break;
            }
            if (map.get(curWord) > wordsMap.get(curWord)) {
                break;
            }
            curLength += n;
        }
        if (curLength === m) {
            res.push(i);
        }
    }
    return res;
};

image.png