问题描述
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.
For example, given:
S:"barfoothefoobarman"
L:["foo", "bar"]
You should return the indices:[0,9].
(order does not matter).
问题分析
这题其实就是子串匹配,每次截取部分子串来与字典进行匹配即可,由于字典中长度是确定的,所以很方便进行循环,最外循环只需要O(n)即可。思路是对的,但是老是不能AC,最后只能从网上抄了一个解法...
详情见CSDN博客,最后要把res排下序,要不过不了AC。
代码实现
public ArrayList<Integer> findSubstring(String S, String[] L) {
ArrayList<Integer> res = new ArrayList<Integer>();
if (S == null || S.length() == 0 || L == null || L.length == 0)
return res;
HashMap<String, Integer> map = new HashMap<String, Integer>();
for (int i = 0; i < L.length; i++) {
if (map.containsKey(L[i])) {
map.put(L[i], map.get(L[i]) + 1);
} else {
map.put(L[i], 1);
}
}
for (int i = 0; i < L[0].length(); i++) {
HashMap<String, Integer> curMap = new HashMap<String, Integer>();
int count = 0;
int left = i;
for (int j = i; j <= S.length() - L[0].length(); j += L[0].length()) {
String str = S.substring(j, j + L[0].length());
if (map.containsKey(str)) {
if (curMap.containsKey(str))
curMap.put(str, curMap.get(str) + 1);
else
curMap.put(str, 1);
if (curMap.get(str) <= map.get(str))
count++;
else {
while (curMap.get(str) > map.get(str)) {
String temp = S.substring(left, left + L[0].length());
if (curMap.containsKey(temp)) {
curMap.put(temp, curMap.get(temp) - 1);
if (curMap.get(temp) < map.get(temp))
count--;
}
left += L[0].length();
}
}
if (count == L.length) {
res.add(left);
String temp = S.substring(left, left + L[0].length());
if (curMap.containsKey(temp))
curMap.put(temp, curMap.get(temp) - 1);
count--;
left += L[0].length();
}
} else {
curMap.clear();
count = 0;
left = j + L[0].length();
}
}
}
Collections.sort(res);
return res;
}
网友评论