Substring with Concatenation of All Words

You are given a string, s, and a list of words, words, that are all of the same length. Find all starting indices of substring(s) in s that is a concatenation of each word in words exactly once and without any intervening characters.

For example, given:
s: "barfoothefoobarman"
words: ["foo", "bar"]

You should return the indices: [0,9].

分析:

第一种方式:把words加到hashmap里,然后从i开始,逐一查看是否每个word都在hashmap里,如果存在,则把hashmap中word所对应的count-1,如果hashmap为空,这表示所有的words都已经获取到了,把starting Index加入到list。

但是这种方式过不了。擦。

 1 public class Solution {
 2     public List<Integer> findSubstring(String s, String[] words) {
 3         List<Integer> list = new ArrayList<>();
 4         if (s == null || s.length() == 0 || words == null || words.length == 0)
 5             return list;
 6 
 7         int length = words[0].length();
 8         for (int i = 0; i < s.length(); i++) {
 9             Map<String, Integer> map = getMap(words);
10             int index = i;
11             boolean allContained = true;
12             while (!map.isEmpty()) {
13                 if (index + length > s.length()) {
14                     allContained = false;
15                     break;
16                 }
17                 String sub = s.substring(index, index + length);
18                 if (map.containsKey(sub)) {
19                     map.put(sub, map.get(sub) - 1);
20                     if (map.get(sub) == 0) {
21                         map.remove(sub);
22                     }
23                     index += length;
24                 } else {
25                     allContained = false;
26                     break;
27                 }
28             }
29 
30             if (allContained) {
31                 list.add(i);
32             }
33         }
34         return list;
35     }
36 
37     private Map<String, Integer> getMap(String[] words) {
38         Map<String, Integer> map = new HashMap<>();
39 
40         for (String str : words) {
41             map.put(str, map.getOrDefault(str, 0) + 1);
42         }
43         return map;
44     }
45 }

还有一种方法,就是先一个window去覆盖S,使得被words里的word都在被覆盖的substring里,那么对于下一个,我们需要把window左边的部分右移一个word出来,这样右边可以继续移动。如果我们当前右边要加入的word已经加够了,或者不存在于words里,我们也需要移动window左边的pointer。很可惜的是,这种方法也过不了,不管了。

 1 public List<Integer> findSubstring(String s, String[] words) {
 2         Map<String, Integer> all = getMap(words);
 3         List<Integer> list = new ArrayList<>();
 4         if (s == null || s.length() == 0 || words == null || words.length == 0)
 5             return list;
 6 
 7         int length = words[0].length();
 8         for (int i = 0; i < length; i++) {
 9             Map<String, Integer> map = getMap(words);
10             int index = i;
11             int starting = i;
12             while (index + length <= s.length()) {
13                 String sub = s.substring(index, index + length);
14                 if (map.containsKey(sub)) {
15                     map.put(sub, map.get(sub) - 1);
16                     if (map.get(sub) == 0) {
17                         map.remove(sub);
18                     }
19                     // find all the words in the hashmap
20                     if (map.isEmpty()) {
21                         list.add(starting);
22                         map.put(s.substring(starting, starting + length), 1);
23                         starting = starting + length;
24                     }
25                 } else {
26                     if (all.containsKey(sub)) {
27                         map.put(s.substring(starting, starting + length),
28                                 map.getOrDefault(s.substring(starting, starting + length), 0) + 1);
29                         starting = starting + length;
30                         continue;
31                     } else {
32                         map = getMap(words);
33                         starting = index + length;
34                     }
35                 }
36                 index += length;
37             }
38         }
39         return list;
40     }
41 
42     private Map<String, Integer> getMap(String[] words) {
43         Map<String, Integer> map = new HashMap<>();
44 
45         for (String str : words) {
46             map.put(str, map.getOrDefault(str, 0) + 1);
47         }
48         return map;
49     }

 

posted @ 2016-08-08 02:47  北叶青藤  阅读(203)  评论(0编辑  收藏  举报