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; } }