Substring with Concatenation of All Wordsjava
比较复杂的一题,首先是要明确用滑块的概念来解决,始终保持L
集合中的字符串在滑块中都只出现了一次,固然设置一个总计数count
,当cout
等于L
集合长度时,即便找了一段符合要求的字符串。数组
须要用到的内存空间:code
L
集合中的单词,一张用来保存当前滑块中的单词,key
为单词,value
为出现次数cout
计数,保存当前滑块中的单词总数left
标记,记录滑块左起点实现的步骤:内存
L
集合,构造总单词表cout
置零,将left
移动到下一位置count
计数加1,进入步骤5;反之,进入步骤4left
收缩滑块,直到收缩到与当前单词相同的字符串片断,将其剔除以后,滑块的收缩工做完成count
计数等于单词集合长度,记录下left
左起点的位置后,将left
右移,当前滑块中相应单词计数减1,总计数减1,继续循环这里解释下步骤4中的收缩滑块,这是由于当前滑块中有单词的出现次数超过了额定的出现次数,那么就是须要收缩滑块来剔除这个单词,至关因而从滑块的左起点开始寻找该单词,找到以后,将该单词的右端点做为滑块新的左起点,这样就保证了滑块中全部单词都是小于等于额定出现次数,这样也保证了count
计数的有效性。leetcode
遇到总单词表中不存在的单词的状况,在步骤2中已经说明,清空当前数据以后继续循环,也就是保证了滑块中是不会出现不存在单词表中的单词的。字符串
最后,考虑最外圈循环,若是是从0开始做为滑块的初始起点,那么其实并无遍历字符串中的全部可能子串,由于步长是单词长度,因此移动滑块的时候会跨过不少可能子串,因此要在外圈再加一层循环,这个循环的做用就是移动滑块的初始起点,因此循环次数就是单词的长度。get
实现代码:string
javapublic class Solution { public List<Integer> findSubstring(String S, String[] L) { ArrayList<Integer> result = new ArrayList<Integer>(); if (S == null || S.length() == 0 || L == null || L.length == 0) return result; int strLen = S.length(); int wordLen = L[0].length(); 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 < wordLen; i++) { HashMap<String, Integer> curMap = new HashMap<String, Integer>(); int count = 0, left = i; for (int j = i; j <= strLen - wordLen; j += wordLen) { String curStr = S.substring(j, j + wordLen); if (map.containsKey(curStr)) { if (curMap.containsKey(curStr)) { curMap.put(curStr, curMap.get(curStr) + 1); } else { curMap.put(curStr, 1); } if (curMap.get(curStr) <= map.get(curStr)) { count++; } else { while (true) { String tmp = S.substring(left, left + wordLen); curMap.put(tmp, curMap.get(tmp) - 1); left += wordLen; if (curStr.equals(tmp)) { break; } else { count--; } } } if (count == L.length) { result.add(left); String tmp = S.substring(left, left + wordLen); curMap.put(tmp, curMap.get(tmp) - 1); left += wordLen; count--; } } else { curMap.clear(); count = 0; left = j + wordLen; } } } return result; } }