题解:
- 题目可以转换为:把字符串s按word的长度划分为一堆集合后,然后这一堆集合中,找出完全由words集合组成的字符串。
- 滑动窗口,每次滑动按一个word的长度滑,当窗口内的元素完全等于words的元素时,此时的下标即为答案。
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
List<Integer> res = new ArrayList<>();
int wsl = words.length;
if (wsl == 0) return res;
int sl = s.length();
int wl = words[0].length();
// 集合1
Map<String, Integer> map1 = new HashMap<>();
for (String word : words) {
Integer wordNum = map1.getOrDefault(word, 0);
map1.put(word, wordNum + 1);
}
for (int i = 0; i < wl; i++) {
// 集合2
Map<String, Integer> map2 = new HashMap<>();
// 此时集合2中拥有集合1中的元素个数
int cnt = 0;
for (int j = i; j + wl <= sl; j += wl) {
// 超过words 能拼凑的最长字符串
if (j >= i + wsl * wl) {
// 窗口右滑,把第一个单词剔除
int startIndex = j - wsl * wl;
String word = s.substring(startIndex, startIndex + wl);
Integer wordNum = map2.getOrDefault(word, 0);
map2.put(word, wordNum - 1);
// 剔除了合法的词
if (map2.getOrDefault(word, 0) < map1.getOrDefault(word, 0)) cnt--;
}
String word = s.substring(j, j + wl);
Integer wordNum = map2.getOrDefault(word, 0);
map2.put(word, wordNum + 1);
if (map2.getOrDefault(word, 0) <= map1.getOrDefault(word, 0)) cnt++;
// 两个集合相等
if (cnt == wsl) res.add(j - (wsl - 1) * wl);
}
}
return res;
}
}
标签:子串,map2,wl,word,int,30,单词,words,wordNum
From: https://www.cnblogs.com/eiffelzero/p/16861809.html