题目描述:
You are given a string, S, and a list of words, L, that are all of the same length. Find all starting indices of substring(s) in S that is a concatenation of each word in L exactly once and without any intervening characters.i
For example, given:
S:"barfoothefoobarman"
L:["foo", "bar"]
You should return the indices:[0,9].
(order does not matter).
思路解析:
- 首先使用HashMap把给出的字符串数组都存起来,使用String作为key,即代码中dict
- 然后因为每个子串的长度相等,所以遍历过程只需要子串长度len次,这是外层循环,因为遍历每个i时都是检查i到i+len的子串是不是在dict里面,然后还会检查i+len到i+2len是不是符合,所以需要len次外循环
- 然后里面的循环是判断初始i,,用j表示,开始以后的每个j+len,j+2len是不是符合dict的key,使用cur表示目前符合的字符串,临时存储
- 注意cur中每个key的数量不能大于dict中的key对应的数目,这样保证出现的次数是符合条件的,给的数组中有几个key,你出现最多也只能有几次。
- count记录数组给的字符串一共出现多少个,是用来判断是不是等于数组长度,如果等于,说明数组中的都找到了,符合条件,加入res中,此时要更新index的值为跳到下一个word,所以从index到index+len的这个word就少一个了,count就减一了,cur里面这个word也要减一了。
代码:
import java.util.*;
public class Solution {
public ArrayList<Integer> findSubstring(String S, String[] L) {
ArrayList<Integer> res = new ArrayList<Integer>();
if(S==null||L==null||S.length()==0||L.length==0)
return res;
HashMap<String,Integer> dict = new HashMap<String,Integer>();
int len = L[0].length();
for(String word :L){
if(!dict.containsKey(word))
dict.put(word,1);
else
dict.put(word,dict.get(word)+1);
}
for(int i=0;i<len;i++){
HashMap<String,Integer> cur = new HashMap<String,Integer>();
int count =0;
int index = i;
for(int j=i;j<=S.length()-len;j+=len){
String curword = S.substring(j,j+len);
if(!dict.containsKey(curword)){
cur.clear();
count =0;
index = j+len;
}else{
if(!cur.containsKey(curword)){
cur.put(curword,1);
}else{
cur.put(curword,cur.get(curword)+1);
}
if(cur.get(curword)<=dict.get(curword)){
count++;
}else{
String temp = S.substring(index,index+len);
cur.put(temp,cur.get(temp)-1);
index = index+len;
}
if(count==L.length){
res.add(index);
String temp = S.substring(index,index+len);
cur.put(temp,cur.get(temp)-1);
index = index +len;
count--;
}
}
}
}
Collections.sort(res);
return res;
}
}