题目:30. 串联所有单词的子串
思路:哈希表+字符串+滑动窗口,时间复杂度0(mlen)。
因为每个字符串的长度都相等,在维护窗口i~i+mlen的元素出现情况后,可以从i+len处继续往后移动。细节看注释。
C++版本:
cpp
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
// 答案
vector<int> v;
int n=s.size();
int m=words.size();
int len=words[0].size();
if(n<m*len) return v;
// 从0~len-1开始遍历
for(int i=0;i<len&&i+m*len<=n;i++){
// 哈希表
unordered_map<string,int> mp;
//把words的元素都+1
for(auto x:words){
mp[x]++;
}
// 先维护窗口i~i+m*len的元素出现情况
for(int j=0;j<m;j++){
string t=s.substr(i+j*len,len);
mp[t]--;
if(mp[t]==0){
mp.erase(t);
}
}
// 如果哈希表为空,说明刚好匹配
if(mp.size()==0) v.push_back(i);
// 因为每个字符串的长度都相等,所以可以从i+len处继续往后移动
for(int j=i+len;j+m*len<=n;j+=len){
// 加入新的字符串
string t=s.substr(j+(m-1)*len,len);
mp[t]--;
if(mp[t]==0) mp.erase(t);
// 删掉旧的字符串
t=s.substr(j-len,len);
mp[t]++;
if(mp[t]==0) mp.erase(t);
// 如果哈希表为空,说明刚好匹配
if(mp.size()==0) v.push_back(j);
}
}
return v;
}
};
JAVA版本:
java
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> v=new ArrayList<>();
int n=s.length();
int m=words.length;
int len=words[0].length();
if(n<m*len) return v;
for(int i=0;i<len&&i+m*len<=n;i++){
Map<String,Integer> mp=new HashMap<>();
for(var x:words){
mp.merge(x,1,Integer::sum);
}
for(int j=0;j<m;j++){
String t=s.substring(i+j*len,i+(j+1)*len);
mp.merge(t,-1,Integer::sum);
if(mp.get(t)==0){
mp.remove(t);
}
}
if(mp.isEmpty()) v.add(i);
for(int j=i+len;j+m*len<=n;j+=len){
String t=s.substring(j+(m-1)*len,j+m*len);
mp.merge(t,-1,Integer::sum);
if(mp.get(t)==0) mp.remove(t);
t=s.substring(j-len,j);
mp.merge(t,1,Integer::sum);
if(mp.get(t)==0) mp.remove(t);
if(mp.isEmpty()) v.add(j);
}
}
return v;
}
}
GO版本:
go
func findSubstring(s string, words []string) []int {
v:=[]int{}
n,m:=len(s),len(words)
lens:=len(words[0])
if n<m*lens {
return v
}
for i:=0;i<lens&&i+m*lens<=n;i++ {
mp := make(map[string]int)
for j:=0;j<m;j++ {
mp[words[j]]++
}
for j:=0;j<m;j++ {
t:=s[i+j*lens:i+(j+1)*lens]
mp[t]--
if mp[t]==0 {
delete(mp,t)
}
}
if len(mp) == 0 {
v = append(v, i)
}
for j:=i+lens;j+m*lens<=n;j+=lens {
t:=s[j-lens:j]
mp[t]++
if mp[t]==0 {
delete(mp,t)
}
t=s[j+(m-1)*lens:j+m*lens]
mp[t]--
if mp[t] ==0 {
delete(mp,t)
}
if len(mp) == 0 {
v = append(v, j)
}
}
}
return v
}