LeetCode-Word Break

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = "leetcode",
dict = ["leet", "code"].

Return true because "leetcode" can be segmented as "leet code".

方法1 kmp+动归 复杂度O(n*L) n为字符串长度,L为字典大小

class Solution {
public:
    void BuildKmp(string& s,vector<int>& next){
        if(s.length()<=0)return;
        next[0]=-1;
        if(s.length()==1)return;
        next[1]=0;
        for(int i=2;i<s.length();i++){
            int j=next[i-1];
            while(j>=0&&s[i-1]!=s[j]){
                j=next[j];
            }
            j++;
            next[i]=j;
        }
    }
    bool wordBreak(string s, unordered_set<string> &dict) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        if(dict.size()==0)return false;
        vector<vector<int> > index;
        vector<string> vec(dict.begin(),dict.end());
        vector<int>next;
        index.resize(s.length());
        for(int i=0;i<vec.size();i++){
            next.resize(vec[i].length());
            BuildKmp(vec[i],next);
            int p=0;
            for(int j=0;j<s.length();j++){
                while(p>=0&&s[j]!=vec[i][p]){
                    p=next[p];
                }
                p++;
                if(p==next.size()){
                    index[j-next.size()+1].push_back(i);
                    p=next[p-1];
                    while(p>=0&&s[j]!=vec[i][p]){
                        p=next[p];
                    }
                    p++;
                }
            }
        }
        vector<bool> acc;
        acc.resize(s.length()+1,false);
        acc[s.length()]=true;
        for(int i=s.length()-1;i>=0;i--){
            for(int k=0;k<index[i].size();k++){
                int point=i+vec[index[i][k]].length();
                if(point<=s.length()){
                    if(acc[point]){
                        acc[i]=true;
                        break;
                    }
                }
            }
        }
        return acc[0];
    }
};
View Code

方法2 利用输入字典是一个hash表 枚举可能长度,在hash表中查找,进行动归复杂度 O(n*l) l为n与字典中最长串长度中的小者。

class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
        // Note: The Solution object is instantiated only once and is reused by each test case.
        int maxLen=0;
        for(unordered_set<string>::iterator it=dict.begin();it!=dict.end();it++){
            if( (*it).length()>maxLen)maxLen=(*it).length();
        }
        string tmp;
        vector<bool>acc;
        acc.resize(s.length()+1,false);
        acc[0]=true;
        for(int i=0;i<s.length();i++){
            if(acc[i]){
                int top=min(maxLen,(int)s.length()-i);
                for(int j=1;j<=top;j++){
                    tmp=s.substr(i,j);
                    if(dict.find(tmp)!=dict.end()){
                        acc[i+j]=true;
                    }
                }
            }
        }
        return acc[s.length()];
    }
};
View Code
原文地址:https://www.cnblogs.com/superzrx/p/3353153.html