30. Substring with Concatenation of All Words

来源:互联网 发布:网络基础知识有哪些 编辑:程序博客网 时间:2024/05/21 22:38

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].
(order does not matter).

  • 方法一:穷搜。把words存入一个HashMap中,键为words,值为words的个数;从每一个位置开始,搜索是否能组成一个concatennation。但提交发现真的太慢了。
 public List<Integer> findSubstring(String S, String[] L){       List<Integer> res = new ArrayList<Integer>();        if (S == null || L == null || L.length == 0) return res;        int len = L[0].length(); // length of each word        Map<String, Integer> map = new HashMap<String, Integer>(); // map for L        for (String w : L) map.put(w, map.containsKey(w) ? map.get(w) + 1 : 1);        for (int i = 0; i <= S.length() - len * L.length; i++) {            Map<String, Integer> copy = new HashMap<String, Integer>(map);            for (int j = 0; j < L.length; j++) { // checkc if match                String str = S.substring(i + j*len, i + j*len + len); // next word                if (copy.containsKey(str)) { // is in remaining words                    int count = copy.get(str);                    if (count == 1) copy.remove(str);                    else copy.put(str, count - 1);                    if (copy.isEmpty()) { // matches                        res.add(i);                        break;                    }                } else break; // not in L            }        }         return res;    }
  • 另外一种方法。时间复杂度为O(n)
public List<Integer> findSubstring(String S, String[] L){        List<Integer> res = new ArrayList<Integer>();        if (S == null || L == null || L.length == 0) return res;        int len = L[0].length(); // length of each word        int l = S.length();        int nums = L.length;        Map<String, Integer> map = new HashMap<String, Integer>(); // map for L        for (String w : L) map.put(w, map.containsKey(w) ? map.get(w) + 1 : 1);        //数组记录从i开始的长为len的字符串是否在words中,并记录其值        String[] str = new String[l - len + 1];        for(int i = 0;i < str.length;i++){            String tmp = S.substring(i,i+len);            if(map.containsKey(tmp)){                str[i] = tmp;            }            else{                str[i] = "";            }        }        //遍历方式为0,0+len,.....;1,1+len,.....;故复杂度为O(n)        for(int i = 0;i < len;i++){            int start = i;            int count = 0;            Map<String, Integer> dic = new HashMap<String, Integer>();             for(int j = i;j <= l - len;j += len){                String tmp = str[j];                if(tmp.equals("")){                    dic.clear();                    count = 0;                    start = j+len;                    continue;                }                else{                    dic.put(tmp, dic.containsKey(tmp) ? dic.get(tmp) + 1 : 1);                    count++;                }                //tmp出现次数超过words中的次数,将第一个dic中的第一个tmp及其之前从dic中删除                if(dic.get(tmp) > map.get(tmp)){                    while(!str[start].equals(tmp)){                        dic.put(str[start],dic.get(str[start])-1);                        start += len;                        count--;                    }                    dic.put(str[start],dic.get(str[start])-1);                    start += len;                    count--;                }                if(count == nums) res.add(start);            }        }        return res;    }
0 0
原创粉丝点击