优化前的代码由LeetCode大佬写,优化后是我写的:
优化后:优化思路
例如s="efabcdabcdab", words=["ab","cd","ab"], 初始map={<"ab", 2>, <"cd", 1>}, 初始放置subMap={<"ef", 1>, <"ab", 1>,<"cd", 1>};
map是否与subMap相等,不等,则移掉"ef", 加入"ab", "efabcdabcdab"----》"
efabcdabcdab";map是否与subMap相等,此时相等,将2加入list, list=[2], 则移掉"ab", 加入"cd", "
efabcdabcdab"----》"efabcdabcdab";map是否与subMap相等,不等,则减少掉1个"cd", 加入"ab","
efabcdabcdab"----》"efabcdabcdab";map是否与subMap相等,此时相等,将6加入list, list=[2,6], 结束index=0的循环,
下次循环index=1,subMap依次为蓝色部分,"efabcdabcdab"----》"e
fabcdabcdab"----》"efabcdabcdab",都不等index=2=一个档次的长度,跳出循环。
最终返回list=[2,6]
public static List<Integer> findSubstring(String s, String[] words) {
List<Integer> list = new ArrayList<>();
if(s==null||s.length()==0||words==null||words.length==0) return list;
int wordLen = words[0].length(), wordNum = words.length, patternLen = wordLen*wordNum;
if(patternLen>s.length()){
return list;
}
Map<String, Integer> map = new HashMap<>();
for(int i = 0; i < wordNum; i++){
map.put(words[i], map.getOrDefault(words[i],0)+1);
}
for(int index = 0; index < wordLen; index++) {//为了减少工作量之前的循环其实重复做了put操作
HashMap<String, Integer> subMap = new HashMap<>();
String temp;
int j = index;
boolean flag = true;
for(; j < s.length()-wordLen+1&&j<patternLen+index; j=j+wordLen){//放置一开始subMap
temp = s.substring(j, j+wordLen);
subMap.put(temp, subMap.getOrDefault(temp, 0)+1);
}
j = index;
for(; j < s.length()-patternLen;j = j + wordLen) {
if(subMap.equals(map)) {
list.add(j);
}
temp = s.substring(j, j+wordLen);
Integer num =subMap.get(temp);
if(num==null||num==1) {
subMap.remove(temp);
}else {
subMap.put(temp, subMap.get(temp)-1);
}
if(j+patternLen+wordLen > s.length()){
break;
}
temp = s.substring(j+patternLen, j+patternLen+wordLen);
subMap.put(temp, subMap.getOrDefault(temp, 0)+1);
}
if(subMap.equals(map)) {
list.add(j);
}
}
return list;
}
优化前
public static List<Integer> findSubstring(String s, String[] words) {
List<Integer> res = new ArrayList<>();
if (s == null || s.length() == 0 || words == null || words.length == 0) return res;
HashMap<String, Integer> map = new HashMap<>();
int one_word = words[0].length(), word_num = words.length, all_len = one_word * word_num;
for (String word : words) {
map.put(word, map.getOrDefault(word, 0) + 1);//每个单词 在单词 里面的个数
}
for (int i = 0; i < s.length() - all_len + 1; i++) {
String tmp = s.substring(i, i + all_len); //所有的单词组合成的字符串的长度
HashMap<String, Integer> tmp_map = new HashMap<>();
for (int j = 0; j < all_len; j += one_word) {
String w = tmp.substring(j, j + one_word);
tmp_map.put(w, tmp_map.getOrDefault(w, 0) + 1);
}
if (map.equals(tmp_map)) res.add(i);//相同的时候hashmap会相等,因为hashmap就是根据hashcode实现的
}
return res;
}
//作者:powcai
//链接:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/solution/chuan-lian-suo-you-dan-ci-de-zi-chuan-by-powcai/
//来源:力扣(LeetCode)
//著作权归作者所有 商业转载请联系作者获得授权 非商业转载请注明出处。