给定一个字符串 s 和一个字符串数组 words,数组中所有字符串长度相同。s 中的串联子串是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。找出所有串联子串在 s 中的起始索引。
["foo","bar"] 顺序排列的连接。
["bar","foo","the"] 顺序排列的连接。
使用滑动窗口(双指针)和哈希表的方法解决该问题:
words 中的所有单词存入哈希表 wordCount,记录每个单词的出现次数。s,以每个可能的起始位置作为窗口的起点,通过滑动窗口判断是否能匹配所有单词。words 中所有单词的总长度。currentWords。words 中的单词匹配,则将起点加入结果列表。public List<Integer> findSubstring(String s, String[] words) {
List<Integer> result = new ArrayList<>();
if (s == null || s.isEmpty() || words == null || words.length == 0) {
return result;
}
Map<String, Integer> wordCount = new HashMap<>();
int wordLength = words[0].length();
int totalLength = wordLength * words.length;
for (String word : words) {
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
}
for (int i = 0; i <= s.length() - totalLength; i++) {
Map<String, Integer> currentWords = new HashMap<>();
int j = 0;
while (j < words.length) {
String currentWord = s.substring(i + j * wordLength, i + (j + 1) * wordLength);
if (!wordCount.containsKey(currentWord)) {
break;
}
currentWords.put(currentWord, currentWords.getOrDefault(currentWord, 0) + 1);
if (currentWords.get(currentWord) > wordCount.getOrDefault(currentWord, 0)) {
break;
}
j++;
}
if (j == words.length) {
result.add(i);
}
}
return result;
}s 的长度,m 是单词数组 words 的长度。wordCount 和 currentWords 的空间复杂度为单词数组 words 的长度。设计不同测试用例,包括空字符串、单个单词、多个单词等情况,验证算法的正确性和效率。
通过本文的详细解题思路和算法实现,可以有效地解决给定字符串中找出所有串联子串的起始索引的问题。利用滑动窗口和哈希表的方法,可以高效地实现该算法。