LeetCode(139)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".


分析如下:

题目意思是,给定词典的情况下,看看原字符串能不能全部成功地被给定的词典分割。一开始,最自然的想法是,使用递归。提交,超时了。想想,这个问题其实具有动态规划的特点。比如计算catsanddog的分割方式,那么倒着想如下:
到了最后一个字符g的时候,
如果能在g之前切一刀,也就是说,如果g在词典中以及catsanddo能够成功切分,那么原字符串就可以成功切分。
或者,如果能在og之前切一刀,也就是说,如果og在词典中以及catsandd能够成功切分,那么原字符串就可以成功切分。
或者,如果能在dog之前切一刀,也就是说,如果dog在词典中以及catsand能够成功切分,那么原字符串就可以成功切分。
或者,如果能在ddog之前切一刀,也就是说,如果ddog在词典中以及catsan能够成功切分,那么原字符串就可以成功切分。
或者,如果能在nddog之前切一刀,也就是说,如果nddog在词典中以及catsa能够成功切分,那么原字符串就可以成功切分。
或者,如果能在anddog之前切一刀,也就是说,如果anddog在词典中以及cats能够成功切分,那么原字符串就可以成功切分。
或者,如果能在sanddog之前切一刀,也就是说,如果sanddog在词典中以及cat能够成功切分,那么原字符串就可以成功切分。
或者,如果能在tsanddog之前切一刀,也就是说,如果tsanddog在词典中以及ca能够成功切分,那么原字符串就可以成功切分。
或者,如果能在atsanddog之前切一刀,也就是说,如果atsanddog在词典中以及c能够成功切分,那么原字符串就可以成功切分。
或者,如果能在catsanddog之前切一刀,也就是说,如果catsanddog在词典中以及""能够成功切分,那么原字符串就可以成功切分。
使用一个数组bool wordB[i] 来记录,在单词长度为i的时候,能否成功切分(i取值范围必然为[ 0, word.length() ] )

我的代码:

第一版

//第一版,递归超时
class Solution {
public:
    bool wordBreak_(string s, unordered_set<string> &dict) {
        if(s.length()==0)
            return true;
        bool ret=false;
        if(s.length()){
            std::cout<<"s="<<s<<std::endl;
            for(unordered_set<string>::iterator it =dict.begin();it!=dict.end();it++){
                if(s.find(*it)==0){
                    bool small_ret=true;
                    std::cout<<"small_ret->"<<*it<<std::endl;
                    string tmp=s.substr((*it).length());
                    std::cout<<"tmp="<<tmp<<std::endl;
                    small_ret=small_ret&&wordBreak_(tmp,dict);
                    if(small_ret==false)
                        continue;
                    ret=ret||small_ret;
                    if(ret==true)
                        break;
                }
            }
        }
        return ret;
    }
    bool wordBreak(string s, unordered_set<string> &dict) {
        if(s.length()==0)
            return false;
        return wordBreak_(s,dict);
    }
};


第二版

// 第二版 参考leetcode官网上的答案
class Solution { 
public:
bool wordBreak(string s, unordered_set<string> &dict) {
    vector<bool> wordB(s.length() + 1, false);
    wordB[0] = true;
    for (int i = 1; i < s.length() + 1; i++) {
        for (int j = i - 1; j >= 0; j--) {
            if (wordB[j] && dict.find(s.substr(j, i - j)) != dict.end()) {
                wordB[i] = true;
                break; //只要找到一种切分方式就说明长度为i的单词可以成功切分,因此可以跳出内层循环。
            }
        }
    }
    return wordB[s.length()];
    }
};


update: 2015-04-09

//16ms
class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
        vector<bool> result(s.length(), false);
        for (int i = 0; i < result.size(); ++i) {
            if (dict.find(s.substr(0, i + 1)) != dict.end()) {
                result[i] = true;
                continue;
            }
            for (int j = 0; j < i; ++j) {
                if ((result[j] == true) && (dict.find(s.substr(j + 1, i -j))!= dict.end())) {
                    result[i] = true;
                    break;
                }
            }
        }
        return result[result.size() - 1];
    }
};


你可能感兴趣的:(LeetCode,递归,动态规划)