LeetCode-30-串联所有单词的子串
in LeetCode with 0 comment

LeetCode-30-串联所有单词的子串

in LeetCode with 0 comment

原题地址:串联所有单词的子串

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

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

示例 1:

输入:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoor" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。

示例 2:

输入:
  s = "wordgoodgoodgoodbestword",
  words = ["word","good","best","word"]
输出:[]

暴力循环

找到s中所有可能的子串,判断是否满足条件即可。由于题目给定的words中所有的单词长度都是相同的,所以判断子串是否满足条件时,我们可以先判断该子串最前面的部分是否在words中存在,如果不存在,那显示不满足条件;如果存在,则判断下一部分在排除掉该单词的剩余数组中是否存在,依此类推,直接某一部分不存在或全部存在为止。

如示例2中s的第一个子串wordgoodgoodgood的判断,先判断word是存在于words中的。排除掉wordwords变成了["good","best","word"],再判断good是存在于这个数组中的,继续排除掉goodwords变成了["best","word"],此时子串的第三部分依然是good,但已不存在于words中了,所以该子串是不满足条件的。

具体实现如下:

/**
 * @param {string} s
 * @param {string[]} words
 * @return {number[]}
 */
const findSubstring1 = function(s, words) {
    if (words.length === 0 || words[0].length === 0) {
        return []
    }
    // 如果s的长度比words中所以单词的长度加起来要短,显然是不满足条件的
    if (s.length < words.length * words[0].length) {
        return []
    }
    let result = [];
    for (let i = 0; i < s.length - words.length * words[0].length + 1; i ++) {
        let temp = [...words]; // 用来记录改变后的words
        let j = 0;
        while (j < words.length) {
            let index = temp.indexOf(s.substr(i + j * words[0].length, words[0].length));
            if (index === -1) { // words中不存在子串的对应部分,匹配失败
                break;
            }
            temp.splice(index, 1); // words中删除子串的对应单词
            j ++;
        }
        if (j === words.length) { // 匹配成功,加入到结果集
            result.push(i);
        }
    }
    return result;
};

测试:

let start = new Date();
const test = findSubstring1;
console.log(test("barfoothefoobarman", ["foo","bar"])); // [ 0, 9 ]
console.log(test("wordgoodgoodgoodbestword", ["word","good","best","good"])); // [ 8 ]
console.log(new Date().getTime() - start.getTime()); // 10

时间复杂度: 时间复杂度为$O(m\times n)$,其中$m$为s的长度,$n$为words中单词的个数
空间复杂度: 需要一个数组来复制words,所以空间复杂度为$O(n)$,其中$n$为words中单词的个数