標籤:discus 中間 暴力 描述 default str log com 不同
題目描述:
給定一個字串 s 和一些長度相同的單詞 words。在 s 中找出可以恰好串聯 words 中所有單詞的子串的起始位置。
注意子串要與 words 中的單詞完全符合,中間不能有其他字元,但不需要考慮 words 中單詞串聯的順序。
樣本 1:輸入: s = "barfoothefoobarman", words = ["foo","bar"]輸出: [0,9]解釋: 從索引 0 和 9 開始的子串分別是 "barfoor" 和 "foobar" 。輸出的順序不重要, [9,0] 也是有效答案。
樣本 2:輸入: s = "wordgoodstudentgoodword", words = ["word","student"]輸出: []
滑動視窗法:
// 參考部落格: // http://www.cnblogs.com/migoo/p/9454684.html // 用了滑動視窗的方法 public List<Integer> findSubstring(String s, String[] words) { List<Integer> result = new ArrayList<Integer>(); // 如果s,或者是words為空白,那麼也返回一個空的列表 if (s.length() == 0 || s == null || words.length == 0 || words == null){ return result; } int size = words[0].length(), length = words.length; // 把字串數組中的的字串全部插入HashMap中 HashMap<String, Integer> map = generate(words); // 視窗的不同的起點,有size個不同的起點 for (int i = 0; i < size; i++){ HashMap<String, Integer> window= new HashMap<>(); // 一個滑動的視窗 int left,right; left = right = i; while (right <= s.length() - size && left <= s.length() - length * size){ String word = s.substring(right, right + size); incr(window, word); if (!map.containsKey(word)){ window.clear(); right += size; left = right; continue; } while (window.get(word) > map.get(word)){ String w = s.substring(left, left + size); decr(window, w); left += size; } right += size; if (right - left == size * length){ result.add(left); } } } return result; } private HashMap<String, Integer> generate(String[] strs){ HashMap<String, Integer> map = new HashMap<>(); for (String str : strs){ incr(map, str); } return map; } private void incr(HashMap<String, Integer> map, String str) { map.put(str, map.getOrDefault(str,0) + 1); } private void decr(HashMap<String, Integer> map, String str) { Integer num = map.get(str); if (num <= 1){ map.remove(str); }else { map.put(str, num - 1); } }
暴力法:
// 參考部落格 // https://www.nowcoder.com/discuss/87526?type=0&order=0&pos=11&page=0 // 暴力法 public List<Integer> findSubstring(String s, String[] words) { List<Integer> result = new ArrayList<Integer>(); if (s.length() == 0 || s == null || words.length == 0 || words == null){ return result; } int size = words[0].length(); int length = words.length; // 截取字串時,取左不取右,所以這裡的for迴圈中i的最大值可以取等號 for (int i = 0; i <= s.length() - size * length; i++){ HashMap<String, Integer> map = new HashMap<>(); for (String word : words){ map.put(word, map.getOrDefault(word, 0) + 1); } if (check(s,i,map,size)){ result.add(i); } } return result; } private boolean check(String s, int i, HashMap<String, Integer> map, int size) { if (map.size() == 0){ return true; } if (i > s.length() || i + size > s.length()){ return false; } String word = s.substring(i, i + size); if (!map.containsKey(word)){ return false; }else { Integer num = map.get(word); if (num <= 1){ map.remove(word); }else { map.put(word, num - 1); } return check(s, i + size, map, size); } }
30. 與所有單詞相關聯的字串、java實現