LeetCode-30. 与所有单词相关联的字串

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/l718531794/article/details/85065194

题目地址:https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/
思路:这题解法不优雅,几乎是卡着过去的,跑了136ms。思路KMP得到出现的所有的位置,然后划框统计区域内出现的单词数量,不加剪枝200ms左右,加上一些剪枝,就能跑进150ms了。
AC代码:

class Solution {
public:
    int Next[1005][1005];
    void getNext(string s2,int k){
        int i,j;
        int len2 = s2.length();
        Next[k][0] = j =-1;
        i = 0;
        while(i<len2){
            while(j!=-1 && s2[i]!=s2[j])
                j = Next[k][j];
            Next[k][++i] = ++j;
        }
    }
    
    vector<int> kmp(string s1,string s2,int k){
        vector<int>pos;
        int len1 = s1.length();
        int len2 = s2.length();
        int i,j;
        i = j = 0;
        while(i<len1){
            while(j!=-1 && s1[i]!=s2[j])
                j = Next[k][j];
            i++;
            j++;
            if(j == len2){
                pos.push_back(i-j);
                j = Next[k][j];
            }   
        }
        return pos;
    }
    
    vector<int> findSubstring(string s, vector<string>& words) {
        map<string,int>w;
        set<int>x[1005];
        int  n = words.size(); 
        vector<int>ans;
        cout<<s.size()<<endl;
        if(n==0 || s.length() == 0)
            return ans;
        int length = words[0].length();
        vector<vector<int> >pos;
        int res = 0;
        for(int i=0;i<n;i++){
            if(!w.count(words[i])){
                getNext(words[i],i);
                pos.push_back(kmp(s,words[i],i));
                w[words[i]] = i;
                res++;
            }else{
                x[w[words[i]]].insert(i);
            }
        }
        //cout<<res<<endl;
        int flag[10005];
        memset(flag,0x3f3f3f3f,sizeof(flag));
        for(int i=0;i<n;i++){
            if(w[words[i]]!=i)
                continue;
            int n_pos = pos[i].size();
            for(int j=0;j<n_pos;j++){
                flag[pos[i][j]] = i;
            }
        }
        int len = s.size();
        for(int i =0;i<=len-n*length ;i++){
            set<int>temp;
            map<int,int>m;
            temp.insert(0x3f3f3f3f);
           for(int j = i;j<i+n*length;j+=length){
               int now = flag[j]; 
               if(now==0x3f3f3f3f)
                   break;
               temp.insert(now);
               if(m.count(now)==0)
                   m[now] = 0;
               m[now]++;
               if(m[now] > x[now].size()+1)
                   break;
           }
            int sum = 0;
            set<int>::iterator it;
            for(it = temp.begin();it!=temp.end();it++){
                if(*it == 0x3f3f3f3f)
                    continue;
                if(x[*it].size()+1 >= m[*it])
                    sum+=m[*it];
                else
                    break;
            }
            if(sum == n)
                ans.push_back(i);
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/l718531794/article/details/85065194