Substring with Concatenation of All Words
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).
Java AC
public class Solution { public ArrayList<Integer> findSubstring(String S, String[] L) { ArrayList<Integer> list = new ArrayList<Integer>(); int len = L.length; if (len == 0) { return list; } int wordLen = L[0].length(); Map<String, Integer> wordsMap = new HashMap<String, Integer>(); for (int i = 0; i < len; i++) { int num = 1; if (wordsMap.get(L[i]) != null) { num += wordsMap.get(L[i]); } wordsMap.put(L[i], num); } int slen = S.length(); int max = slen - len * wordLen + 1; for (int i = 0; i < max; i++) { Map<String, Integer> numMap = new HashMap<String, Integer>(); int j = 0; for (; j < len; j++) { int start = i + j * wordLen; int end = start + wordLen; String tempStr = S.substring(start, end); if (!wordsMap.containsKey(tempStr)) { break; } int num = 1; if (numMap.get(tempStr) != null) { num += numMap.get(tempStr); } if (num > wordsMap.get(tempStr)) { break; } numMap.put(tempStr, num); } if (j == len) { list.add(i); } } return list; } }2、最小滑动窗口(Java AC的代码是448ms) 因为L中所有单词的长度是一样的,这样根据wordLen,可以将S分为wordLen组,实际意思是这样的。
Java AC
public class Solution { public ArrayList<Integer> findSubstring(String S, String[] L) { ArrayList<Integer> list = new ArrayList<Integer>(); int len = L.length; if (len == 0) { return list; } int wordLen = L[0].length(); Map<String, Integer> wordsMap = new HashMap<String, Integer>(); for (int i = 0; i < len; i++) { int num = 1; if (wordsMap.get(L[i]) != null) { num += wordsMap.get(L[i]); } wordsMap.put(L[i], num); } int slen = S.length(); int max = slen - wordLen + 1; for (int i = 0; i < wordLen; i++) { Map<String, Integer> numMap = new HashMap<String, Integer>(); int count = 0; int start = i; for (int end = start; end < max; end += wordLen) { String tempStr = S.substring(end, end + wordLen); if (!wordsMap.containsKey(tempStr)) { numMap.clear(); count = 0; start = end + wordLen; continue; } int num = 1; if (numMap.containsKey(tempStr)) { num += numMap.get(tempStr); } numMap.put(tempStr, num); if (num <= wordsMap.get(tempStr)) { count++; } else { while (numMap.get(tempStr) > wordsMap.get(tempStr)) { tempStr = S.substring(start, start + wordLen); numMap.put(tempStr, numMap.get(tempStr) - 1); if (numMap.get(tempStr) < wordsMap.get(tempStr)) { count--; } start += wordLen; } } if (count == len) { list.add(start); tempStr = S.substring(start, start + wordLen); numMap.put(tempStr, numMap.get(tempStr) - 1); count--; start += wordLen; } } } return list; } }