给定一个字符串 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”]
输出:[]
这个是子串组合成全串的一种暴力解法,没有通过,就是因为内存不够,但是我这种解法综合Python中全排列的函数外加求子串出现所有的索引。只是因为时间和空间不达标
import itertools
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
all_list = list(itertools.permutations(words))
res = []
if len(s)==0 or len(words)==0:
return res
for i in all_list:
sub = ''
for j in i:
sub = sub+j
if sub in s:
index = s.find(sub)
while index != -1:
if index not in res:
res.append(index)
index = s.find(sub,index+1)
return res
下面应用窗口法,解此题;
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
//排除特殊情况
if(s.empty()||words.empty()){
return {};
}
//最终的结果;
vector<int>res;
//words中单词的个数,单词长度以及总长度;
int num_words = words.size();
int len_words = words[0].size();
int sum_words = num_words*len_words;
// 建立单词与单词个数的映射
unordered_map<string, int>m;
for(const auto&w:words){
m[w]++;
}
for(int i=0;i<len_words;i++){
//l,r分别表示移动窗口的左右边界;count表示匹配的单词的个数;
int l = i,r=i,count = 0;
//主要是为了让单词连续拼接
unordered_map<string,int>n;
while(r+len_words<=s.size()){
//从s中copy一个单词w
string w = s.substr(r,len_words);
//向右移动一个单词的长度;
r = r+len_words;
//判断w在不在words中
//如果不在呢,就有重新设置单词个数,左侧边界,以及n
if(m.count(w)==0){
count = 0;
l = r;
n.clear();
}else{
//如果在words中呢,就要将w放进n
n[w]++;
count++;
//这里面呢,就会有一个问题就是一个单词匹配多次,这时就要移动左侧l
while(n[w]>m[w]){
//重复的单词
string rep_w = s.substr(l,len_words);
count--;
n[rep_w]--;
l = l+len_words;
}
if(count==num_words){
res.push_back(l);
}
}
}
}
return res;
}
};
运用python的模块进行解题:
from collections import Counter
class Solution:
def findSubstring(self, s: str, words: List[str]) -> List[int]:
res = []
if len(words)==0 or len(s)==0:
return []
len_s = len(s)
dict_words = Counter(words)
sum_words = len(words)*len(words[0])
for i in range(0,len_s-sum_words+1):
temp = s[i:i+sum_words]
temp_res = []
for j in range(0,sum_words,len(words[0])):
temp_res.append(temp[j:j+len(words[0])])
temp_dict = Counter(temp_res)
if dict_words==temp_dict:
res.append(i)
return res