开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第37天,点击查看活动详情
题目描述
给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。
s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。
例如,如果 words = ["ab","cd","ef"], 那么 "abcdef", "abefcd","cdabef", "cdefab","efabcd", 和 "efcdab" 都是串联子串。 "acdbef" 不是串联子串,因为他不是任何 words 排列的连接。
返回所有串联字串在 s 中的开始索引。你可以以 任意顺序 返回答案。
来源:力扣(LeetCode)
- 示例 1
输入:s = "barfoothefoobarman", words = ["foo","bar"]
输出:[0,9]
解释:因为 words.length == 2 同时 words[i].length == 3,连接的子字符串的长度必须为 6。
子串 "barfoo" 开始位置是 0。它是 words 中以 ["bar","foo"] 顺序排列的连接。
子串 "foobar" 开始位置是 9。它是 words 中以 ["foo","bar"] 顺序排列的连接。
输出顺序无关紧要。返回 [9,0] 也是可以的。
- 示例 2
输入:s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
输出:[]
解释:因为 words.length == 4 并且 words[i].length == 4,所以串联子串的长度必须为 16。
s 中没有子串长度为 16 并且等于 words 的任何顺序排列的连接。
所以我们返回一个空数组。
思路分析
根据题意可知,题目给出一个字符串s和一个字符串数组words;需要在字符串中找出由字符串数组里面的所有字符串串联起来的子字符串。字符串拼接的位置可以随意放。但是每个字符串里面的字符必须按原来的位置,不能移动。
需要取到每个字符串里面每个字符,然后再一一匹配,所以这里就需要用到for循环。首先,我们先把字符串words的长度和数组words的长度以及数组第一个字符串(因为数组里面的每个字符串长度都是一致的)的长度计算出来。
不在意字符串的位置,所以可以先给数组words排序;数组不方便直接比对,用字符串就可以,所以将数组转化为字符串wordsStr。
按照wordlen的长度,将字符串s切出来,然后再拼接到新数组里面,数组的长度一定要和数组words的长度一致,再排序、转成字符串就和字符串wordsStr比对一下,若是符合就往结果数组res里面添加当前的下标。每次在切字符串时,可以使用字符串的substr方法,计算出每次切的开始位置,长度就是wordlen。
AC代码
function solution(str, words) {
let wordsLeng = words.length;
let strLeng = str.length;
let wordlen = words[0].length;
let currentStr = [];
let res = [];
words.sort();
let wordsStr = words.join('');
for(let i=0; i<strLeng; i++) {
for(let j=0; j<wordsLeng; j++) {
currentStr.push(str.substr(i+wordlen*j, wordlen));
}
currentStr.sort()
if(currentStr.join('') === wordsStr) {
res.push(i);
console.log(currentStr)
}
currentStr = [];
}
console.log(res);
return res;
}
let s = "barfoothefoobarman", words = ["foo","bar"];
solution(s, words);