import java.util.*; public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param s string字符串 * @param words string字符串一维数组 * @return int整型一维数组 */ public int[] findSubstring(String s, String[] words) { List<Integer> result = new ArrayList<>(); // 用于存储符合条件的子串的起始索引 if (s == null || s.length() == 0 || words == null || words.length == 0) { return new int[0]; // 处理边界情况:s为空或长度为0,或者words为空的情况 } Map<String, Integer> wordCountMap = new HashMap<>(); // 用于存储每个单词出现的次数 // 统计单词出现的次数 for (String word : words) { wordCountMap.put(word, wordCountMap.getOrDefault(word, 0) + 1); } int wordLength = words[0].length(); // 单词的长度 int wordsCount = words.length; // words数组中单词的个数 int substrLength = wordLength * wordsCount; // 子串的长度 for (int i = 0; i <= s.length() - substrLength; i++) { // 滑动窗口遍历字符串s Map<String, Integer> tempMap = new HashMap<> (wordCountMap); // 创建临时map,用于记录剩余未匹配的单词及其出现次数 int j = 0; while (j < substrLength) { String word = s.substring(i + j, i + j + wordLength); // 每次从窗口中取出长度为wordLength的单词 if (tempMap.containsKey(word)) { // 如果临时map中包含这个单词 int count = tempMap.get(word); // 取出该单词的出现次数 if (count == 1) { // 如果次数为1,则从临时map中移除这个单词 tempMap.remove(word); } else { // 如果次数大于1,则将这个单词的出现次数更新为count-1 tempMap.put(word, count - 1); } j += wordLength; // 移动到下一个单词的起始位置 } else { break; // 如果单词不在临时map中,说明这个子串不符合条件,跳出循环 } } if (tempMap.isEmpty()) { // 如果临时map为空,表示所有的单词都匹配完毕 result.add(i); // 将当前子串的起始索引加入结果列表 } } // 将结果列表转换为数组 int[] res = new int[result.size()]; for (int i = 0; i < res.length; i++) { res[i] = result.get(i); } return res; // 返回结果数组 } }
本题知识点分析:
1.滑动窗口
2.哈希表的存取
3.集合转数组
4.数组遍历
5.数学模拟
本题解题思路分析:
1.将所有word进行字符串记录,放到map并记录出现的次数
2.这边说主要思想,滑动窗口,建立一个长度为words的窗口,索引增加值为一个单词的长度,然后持续的往右滑动,如果发现这个窗口的字符串和次数都相等map,其实就是全被移除,map为空,那么表示此窗口出现了这个子串,记录这个索引
3.将存储索引的集合转化成数组即可
本题使用编程语言: Java
如果你觉得对你有帮助的话,可以点个赞,感谢~