LeetCode-Substring with Concatenation of All Words

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

For example, given:
S: "barfoothefoobarman"
L: ["foo", "bar"]

You should return the indices: [0,9].
(order does not matter).

 

 

首先合并相同项并统计出现次数

之后通过kmp算法实现O(n*l*k) 复杂度的预处理得出主串上每一位能够匹配的子串的序号,其中n为主串长度,l为所有字串个数,k为子串长度

之后通过O(k*(n/k))复杂度的遍历计算从第i个字符开始,每隔K位的情况 i的取值范围为【0-k)

 

class Solution {
public:
    void BuildKmp(string s,vector<int>& next){
        next[0]=-1;
        next[1]=0;
        for(int j=2;j<s.length();j++){
            int i=next[j-1];
            while(i>=0&&s[i]!=s[j-1]){
                i=next[i];
            }
            i++;
            next[j]=i;
        }
    }
    vector<int> findSubstring(string S, vector<string> &L) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        sort(L.begin(),L.end());
        vector<string> list;
        vector<int> count;
        list.push_back(L[0]);
        count.push_back(1);
        for(int i=1;i<L.size();i++){
            if(L[i]==L[i-1])count[count.size()-1]++;
            else{
                list.push_back(L[i]);
                count.push_back(1);
            }
        }
        int len=list[0].length();
        if(S.length()<L.size()*len)return vector<int>();
        vector<int> next;
        next.resize(len);
        vector<int> index;
        index.resize(S.length(),-1);
        for(int i=0;i<list.size();i++){
            BuildKmp(list[i],next);
            int p=0;
            for(int j=0;j<S.length();j++){
                if(S[j]==list[i][p]){
                    p++;
                    if(p==len){
                        index[j-len+1]=i;
                        p=next[p-1];
                        while(p>=0&&list[i][p]!=S[j]){
                            p=next[p];
                        }
                        p++;
                    }
                }
                else{ 
                    while(p>=0&&list[i][p]!=S[j]){
                        p=next[p];
                    }
                    p++;
                }
            }
        }
        vector<int> count2;
        count2.resize(count.size(),0);
        vector<int>ret;
        for(int i=0;i<len;i++){
            int start=i;
            int end=start;
            for(int mm=0;mm<count2.size();mm++)count2[mm]=0;
            while(true){
                if(index[end]==-1){
                    for(int j=start;j<end;j+=len){
                        count2[index[j]]=0;
                    }
                    end+=len;
                    if(end>=S.length())break;
                    start=end;
                }
                else{

                    while((count2[index[end]]==count[index[end]])){
                        count2[index[start]]--;
                        start+=len;
                    }
                    count2[index[end]]++;
                    if(end-start==(L.size()-1)*len){
                        ret.push_back(start);
                        count2[index[start]]--;
                        start+=len;
                        end+=len;
                        if(end>=S.length())break;
                    }
                    else{
                        end+=len;
                        if(end>=S.length())break;
                    }

                }
            }
        }
        return ret;
    }
};
View Code

 

posted @ 2013-10-05 01:52  懒猫欣  阅读(156)  评论(0编辑  收藏  举报