首页 > 代码库 > leetcode第一刷_Word Break

leetcode第一刷_Word Break

这种题一看,立马就会想到递归,但直接递归的代价太大了,当字典里的单词长度很小,而单词长度很长时,肯定会超时的。再仔细想一下,是不是每次递归验证都是有必要的呢?如果从i位置开始已经被验证为不行了,那么其他递归分支走到这个位置的时候就不用走了,因为肯定是死胡同。想到了打表,把不行的位置记录下来,速度显著提高。

下面说一点实现的事情,记录一个位置行不行,用map最简单直接,查找速度也快。每次选择步长的时候,不用从0到length,我的做法是先统计一下最长和最小的单词长度,每次验证这个长度就可以了。

代码很简单,一般不会出错:

int mmin = 0x7fffffff, mmax = 0;
map<int, bool> visited;
bool pwordBreak(string &s, int start, unordered_set<string> &dict){
    if(start >= s.length())
        return true;
    if(visited.find(start) != visited.end())
        return visited[start];
    for(int i=mmin;i<=mmax&&start+i<=s.length();i++){
        string sb = s.substr(start, i);
        if(dict.find(sb) != dict.end()){
            if(pwordBreak(s, start+i, dict)){
                visited[start+i] = true;
                return true;
            }else{
                visited[start+i] = false;
            }
        }
    }
    return false;
}


class Solution {
public:
    bool wordBreak(string s, unordered_set<string> &dict) {
        unordered_set<string>::const_iterator it = dict.begin();
        while(it != dict.end()){
            mmin = min(mmin, (int)(*it).length());
            mmax = max(mmax, (int)(*it).length());
            it++;
        }
        visited.clear();
        return pwordBreak(s, 0, dict);
    }
};