今天看了下leetcode的第30题,题目链接:30. 串联所有单词的子串
题目如下:
给定一个字符串 s 和一些 长度相同 的单词 words 。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置。
注意子串要与 words 中的单词完全匹配,中间不能有其他字符 ,但不需要考虑 words 中单词串联的顺序。
我这里使用了滑动切割字符串的方式,理解起来相对简单,代码如下;
public static List<Integer> findSubstring(String s, String[] words) {
int sLen = s.length();
int len = words.length;
int length = words[0].length();
Map<String,Integer> map = new HashMap();
List<Integer> list = new ArrayList<>();
//记录words得个数
for(String word : words){
map.put(word,map.getOrDefault(word,0)+1);
}
for (int i = 0; i <= sLen -len*length; i++) {
// 减少比较次数
if(map.containsKey(s.substring(i,i+length))
&& map.containsKey(s.substring(i+(len-1)*length,i+len*length))){
int index = i;
String tmp = "";
Map<String,Integer> tmpMap = new HashMap();
tmpMap.putAll(map);
while(index <= i+(len-1)*length){
tmp = s.substring(index,index+length);
if(tmpMap.containsKey(tmp)){
tmpMap.put(tmp,tmpMap.get(tmp)-1);
if(tmpMap.get(tmp) == 0){
tmpMap.remove(tmp);
}
}else{
break;
}
if(tmpMap.size() == 0){
list.add(i);
}
index += length;
}
}
}
return list;
}