持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第25天,点击查看活动详情
每日刷题 2022.06.23
- leetcode原题链接:leetcode.cn/problems/su…
- 难度:困难
- 方法:暴力、滑动窗口
题目
- 给定一个字符串 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 <= 10^4
- s 由小写英文字母组成
- 1 <= words.length <= 5000
- 1 <= words[i].length <= 30
- words[i] 由小写英文字母组成
解题思路
- 每次看到题目类型,困难,就想睡大觉,hhhh。今天不一样,思考了一下,感觉暴力思路应该也能过,就没有查看题解,硬着头皮做过了,hhhhhh, o( ̄▽ ̄)ブ
- 分析题意:需要输出能够在
s字符串中找到word连续的下标,并且word组成的顺序可以是随意的,但是一定要是连续的。 - 注意⚠️:因为有可能
word中会出现多个相同的字符串,那么就不能只判断这个字符串是否出现过,而是需要判断字符串出现的次数是否满足,如果有一个不满足,那么从当前下标开始的记录,就不成立;反之,如果对于word中的每一个元素都满足,并且所有满足的字符串个数是刚好等于word的长度的话,那么就说明找到了一个连续的符合的字符串,从而在ans数组中记录下当前的下标。 - 以此重复执行,知道
s的每一个元素都被查找完。 - 注意⚠️:题目中给出说
word中的每一个字符串都是等长的(记为n),因此可以每次在s字符串中判断的时候,直接截取长度n,进行比对。
AC代码
/**
* @param {string} s
* @param {string[]} words
* @return {number[]}
*/
var findSubstring = function(s, words) {
// 可以循环遍历对每一个元素进行查找,使用一个vis数组记录,每个是否都被找到过,找到的话,就不能找,同时数组的长度记录,判断是否数组中的元素全部被找到
// 10 ^4 * 5 * 10 ^ 3 = 5 * 10 ^7
let w = words, n = words.length, ns = s.length, len = w[0].length,ans = [];
if(ns < len) return ans;
let vis = new Array(n).fill(0);
for(let i = 0; i < n; i++) {
let index = w.indexOf(w[i]);
vis[index]++;
}
let contra = new Array(n).fill(0);
// console.log('len:::', ns,len)
//每次截取固定长度来进行匹配
for(let i = 0; i < ns - len + 1; i++) {
// console.log(s.substr(i, len));
let num = 0;
contra = new Array(n).fill(0);
for(let j = i; j < ns - len + 1;) {
let cur = s.substr(j, len), idx = w.indexOf(cur);
// console.log('cur:::', cur, idx, contra)
if(idx == -1) break;
if(idx != -1) {
contra[idx]++;
num++;
}
if(contra[idx] > vis[idx]) break;
if(num == n) {
ans.push(i);
}
j += len;
// console.log('end::', j, ns - len + 1)
}
}
return ans;
};