[LeetCode]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 wordsexactly once and without any intervening characters.

Analysis

同样可以采用滑动窗口法解决。在移动的过程中维护一个HashMap的字典,保存查找的字符串状况。

step 1.构建一个HashMap dict的字典,key-value对应words中的word和出现的次数。注意给定的words中可能多次出现同一个word。

step 2.设word的length为wLen(每个word的长度都相同),第一层循环wLen次,每次循环整个字符串。

step 3.第二层循环每次循环前进wLen位,遍历整个字符串,单次循环内次数为s.length()/wLen。这样两层循环就可以覆盖所有可能的字符串。用startIndex记录匹配字符串的开始位置,count记录匹配的字典字符串的个数。用另一个HashMap curMap维护当前匹配字符串中字典字符串的状况。通过比较dict和curMap的key-value来更新count和startIndex。注意:当前匹配的字典字符串在整个匹配字符串中出现的次数超出即curMap.get(sub) > dict.get(sub),那么startIndex应直接移动到该匹配的字典字符串后一次出现位置之后,count同样减小。

packagecom.samxcode.leetcode;
 
importjava.util.ArrayList;
importjava.util.HashMap;
importjava.util.List;
 
/**
 * 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.
 *
 * @author Sam
 *
 */
publicclassFindSubstring {
     
    publicstaticvoidmain(String[] args) {
        String[] words = {"a","b","a"};
        System.out.println(findSubstring("abababab", words));
    }
 
    publicstaticList<Integer> findSubstring(String s, String[] words) {
        List<Integer> res =newArrayList<Integer>();
        if(words.length ==0|| s.length() ==0) {
            returnres;
        }
        intwLen = words[0].length();
        // the count of special words displayed each loop
        intcount;
        // the start index each matching process
        intstartIndex;
        // put the given dictionary into hash map with each word's count
        HashMap<String, Integer> dict =newHashMap<String, Integer>();
        // dictionary in current matching process
        HashMap<String, Integer> curMap =newHashMap<String, Integer>();
        for(String word : words) {
            if(dict.containsKey(word))
                dict.put(word, dict.get(word) +1);
            else
                dict.put(word,1);
        }
        for(inti =0; i < wLen; i++) {
            count =0;
            startIndex = i;
            curMap.clear();
            for(intj = i; j <= s.length() - wLen; j += wLen) {
                // current word
                String sub = s.substring(j, j + wLen);
                if(dict.containsKey(sub)) {
                    // update current dictionary
                    if(curMap.containsKey(sub))
                        curMap.put(sub, curMap.get(sub) +1);
                    else
                        curMap.put(sub,1);
                    count++;
                    // check if count for current found word exceed given word count
                    if(curMap.get(sub) > dict.get(sub)) {
                        // shift the start index to the found word's next word and update the count
                        while(curMap.get(sub) > dict.get(sub)) {
                            String temp = s.substring(startIndex, startIndex + wLen);
                            curMap.put(temp, curMap.get(temp) -1);
                            startIndex += wLen;
                            count--;
                        }
                    }
                    // put the start index into result, shift index to next word, and update current
                    // dictionary and count
                    if(count == words.length) {
                        res.add(startIndex);
                        String temp = s.substring(startIndex, startIndex + wLen);
                        curMap.put(temp, curMap.get(temp) -1);
                        startIndex += wLen;
                        count--;
                    }
                }else{
                    curMap.clear();
                    startIndex = j + wLen;
                    count =0;
                }
 
            }
        }
        returnres;
    }
}

Complexity

第一层循环wLen次,第二层循环n/wLen次,所以时间复杂度O(n),空间复杂度O(d*l),s 字典大小,l 字典字符串长度

你可能感兴趣的:(java,Algorithm,LeetCode,substring,concatenation)