30. Substring with Concatenation of All Words

来源:互联网 发布:苹果大麦网抢票软件 编辑:程序博客网 时间:2024/06/14 15:31

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).

这个题用brute force是AC的,

优化的方案是sliding window,不过要遍历len(word in words)次


import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class Solution {    public List<Integer> findSubstring(String s, String[] words) {    List<Integer> rst = new ArrayList<Integer>();    Map<String, Integer> map = new HashMap<String, Integer>();    int len = words[0].length(), n = words.length;        for(String word : words)map.put(word, map.containsKey(word) ? map.get(word) + 1 : 1);        for(int i=0; i<=s.length()-n*len; i++) {    Map<String, Integer> temp = new HashMap<String, Integer>(map);    boolean f = true;    for(int j=0; j<n*len; j+=len) {    String key = s.substring(i+j, i+j+len);    if(!temp.containsKey(key)){f = false;break; }    int nextVal = temp.get(key)-1;    if(nextVal < 0){f = false;break; }    temp.put(key, nextVal);    }        if(f){rst.add(i);}    }        return rst;    }}

package l30;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;/* * 之前写的暴力解法竟然能过。。。。。 * 用2pointer,可以做到O(len(word in words) * len(s)), * 从s的0..len(word in words)开始分别走一遍sliding window */class AC {    public List<Integer> findSubstring(String s, String[] words) {        List<Integer> ret = new ArrayList<Integer>();        int n = s.length(), m = words[0].length();                for(int i=0; i<m; i++) {        int need = words.length;        // Map还可以优化为不需要每次初始化,在结束当前循环前把p归到q上去        Map<String, Integer> map = new HashMap<String, Integer>();        for(String t : words) map.put(t, map.containsKey(t)?1+map.get(t):1);                // sliding window        int p = i, q = i;        while(true) {        if(need == 0)ret.add(p);        if(q+m > n)break;        String t = s.substring(q, q+m);                if(!map.containsKey(t)) {        // 出现words中没有的,        while(p != q) {        String tt = s.substring(p, p+m);        map.put(tt, map.get(tt) + 1);        p += m;        need ++;        }        q += m;        p = q;        } else if(map.get(t) == 0) {        // 多出个t        while(map.get(t) == 0) {        String tt = s.substring(p, p+m);        map.put(tt, map.get(tt) + 1);        p += m;        need ++;        }        map.put(t, map.get(t) - 1);        need --;        q += m;        } else {        // 正好需要这个string        map.put(t, map.get(t)-1);        need --;        q += m;        }        }        }                return ret;    }}

import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;class Solution {    public List<Integer> findSubstring(String s, String[] words) {        List<Integer> ret = new ArrayList<Integer>();        int n = s.length(), m = words[0].length();        Map<String, Integer> map = new HashMap<String, Integer>();    for(String t : words) map.put(t, map.containsKey(t)?1+map.get(t):1);                for(int i=0; i<m; i++) {        int need = words.length;                // sliding window        int p = i, q = i;        while(true) {        if(need == 0)ret.add(p);        if(q+m > n)break;        String t = s.substring(q, q+m);                if(!map.containsKey(t)) {        // 出现words中没有的,        while(p != q) {        String tt = s.substring(p, p+m);        map.put(tt, map.get(tt) + 1);        p += m;        need ++;        }        q += m;        p = q;        } else if(map.get(t) == 0) {        // 多出个t        while(map.get(t) == 0) {        String tt = s.substring(p, p+m);        map.put(tt, map.get(tt) + 1);        p += m;        need ++;        }        map.put(t, map.get(t) - 1);        need --;        q += m;        } else {        // 正好需要这个string        map.put(t, map.get(t)-1);        need --;        q += m;        }        }                while(p != q) {        String tt = s.substring(p, p+m);map.put(tt, map.get(tt) + 1);p += m;        }        }                return ret;    }}