滑动窗口的思想,将所有子串分为单词长度个元组,作为遍历的外层循环。
内层循环跨度为单词的长度
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
List<Integer>result=new ArrayList<Integer>();
int wordNum=words.length;
if(wordNum==0)
return result;
int wordLen=words[0].length();
HashMap<String,Integer>hashMap1=new HashMap<String,Integer>();
for(String word:words)
{
if(hashMap1.containsKey(word))hashMap1.put(word,hashMap1.get(word)+1);
else hashMap1.put(word,1);
}
//分成wordLen类情况
for(int j=0;j<wordLen;j++)
{
HashMap<String,Integer>hashMap2=new HashMap<String,Integer>();
int num=0;//记录当前HashMap2中有多少个单词与HashMap1匹配
for(int i=j;i<s.length()-wordNum*wordLen+1;i+=wordLen)
{
boolean hasRemoved=false; //防止情况三移除后,情况一继续移除
while(num<wordNum){
String word=s.substring(i+num*wordLen,i+(num+1)*wordLen);
if(hashMap1.containsKey(word)){
int value=hashMap2.getOrDefault(word,0);
hashMap2.put(word,value+1);
if(hashMap2.get(word)>hashMap1.get(word))
{
hasRemoved=true;
int removeNum=0;
while(hashMap2.get(word)>hashMap1.get(word))
{
String curWord=s.substring(i+removeNum*wordLen,i+(removeNum+1)*wordLen);
int v=hashMap2.get(curWord);
hashMap2.put(curWord,v-1);
removeNum++;
}
num=num-removeNum+1;
i=i+(removeNum-1)*wordLen;
break;
}
}
else //情况二,当前单词不在hashMap1
{
hashMap2.clear();
i=i+num*wordLen;
num=0;
break;
}
num++;
}
if(num==wordNum) result.add(i);
if(num==wordNum&&!hasRemoved)
{
String firstWord=s.substring(i,i+wordLen);
int v=hashMap2.get(firstWord);
hashMap2.put(firstWord,v-1);
num=num-1;
}
}
}
return result;
}
}