还好这个题 单词数组的中的单词长度都一致,不然更难做了。
滑动窗口 + 哈希Map
- 思路:因为只考虑串联子串,不考虑顺序,因此我们使用一个HashMap记录每个单词的数量,主要单词数量对得上,就说明是符合结果的答案。
- 基于上述思路,我们将s按照单词长度切割为单词,用一个临时Map记录s中的单词数,使用一个count记录符合要求的单词数,如果最终
count==words.length说明是题目的一个解。
java
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> res = new ArrayList<>();
if(s == null || words == null || s.length() == 0 || words.length == 0) return res;
if(s.length() < words.length * words[0].length()) return res;
// 统计词频
Map<String, Integer> wordCountMap = new HashMap<>();
for(String word : words){
wordCountMap.put(word, wordCountMap.getOrDefault(word, 0) + 1);
}
int wordLen = words[0].length();
int wordNum = words.length;
for(int i = 0; i< wordLen ;i++){
int left = i;
int matchCount = 0;
Map<String, Integer> curCountMap = new HashMap<>();
for(int right = i; right <= s.length() - wordLen; right += wordLen ){
String curWord = s.substring(right, right + wordLen);
if(wordCountMap.containsKey(curWord)){
curCountMap.put(curWord, curCountMap.getOrDefault(curWord, 0) + 1);
matchCount++;
// 向左滑动窗口,直到移动到left符合要求 aaabbbcccbbb ---> 移动到第一个c处
while(wordCountMap.get(curWord) < curCountMap.get(curWord)){
String leftWord = s.substring(left, left + wordLen);
curCountMap.put(leftWord, curCountMap.get(leftWord) - 1);
left += wordLen;
matchCount--;
}
if(matchCount == wordNum){
res.add(left);
}
}else{
curCountMap.clear();
matchCount = 0;
left = right + wordLen;
}
}
}
return res;
}
}