思路:枚举开始划分字符串s的位置[0,n-1],将s划分为单词组,每个单词的长度为word[0].size(),用滑动动窗口求解,方法与LeetCode438.找到字符串中所有字母异位词相同。
/*
* @lc app=leetcode.cn id=30 lang=cpp
*
* [30] 串联所有单词的子串
*/
// @lc code=start
#include<iostream>
#include<vector>
#include<string>
#include<unordered_map>
using namespace std;
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
vector<int>res;
int m=words.size();
int n=words[0].size();
int lens=s.size();
for(int i=0;i<n&&i+m*n<=lens;i++){
unordered_map<string,int>window;
for(string word:words){
window[word]--;
}
for(int start=i;start<m*n+i&&start<lens;start+=n){
string w=s.substr(start,n);
window[w]++;
if(window[w]==0){
window.erase(w);
}
}
if(window.empty()){
res.push_back(i);
}
for(int start=i+n;start<=lens-m*n;start+=n){
string word1=s.substr(start-n,n);
window[word1]--;
if(window[word1]==0){
window.erase(word1);
}
string word2=s.substr(start+(m-1)*n,n);
window[word2]++;
if(window[word2]==0){
window.erase(word2);
}
if(window.empty()){
res.push_back(start);
}
}
}
return res;
}
};
时间复杂度:O(lens×n),其中lens是输入 s 的长度,n 是 words中每个单词的长度。需要做 n 次滑动窗口,每次需要遍历一次 s。
空间复杂度:O(m×n),其中 m 是 words的单词数,n 是 words中每个单词的长度。每次滑动窗口时,需要用一个哈希表保存单词频次。