[leetcode]Word Break II

T_TDP,但是还是DFS+record,我就是这么屌丝

用trie树来加速了下(感觉用处不大

DFS策略就是

从当前往后找,能break就从这里break继续找

如果找到最后,那么就是一个解

record记录的就是从当前位置断开,后面那部分的解vector<string>

如果有了就不用再算了(这个重复很多

然后就是把当前的和后面的拼接起来,当然如果最后是结尾的话特殊处理下,我也不知道vector<string>是否可以null之类的东西

所以我就返回了一个特殊串

struct TrieNode {
    TrieNode* child[26];
    bool is_word;
    TrieNode():is_word(false) {
        for(int i = 0 ; i < 26 ; ++i) {
            child[i] = nullptr;
        }
    }
    void insert(const string& str) {
        TrieNode* curr = this;
        int size = str.size();
        for(int i = 0 ; i < size ; ++i) {
            if(curr->child[str[i]-'a'] != nullptr) 
                curr=curr->child[str[i]-'a'];
            else {
                curr->child[str[i]-'a'] = new TrieNode();
                curr = curr->child[str[i]-'a'];
            }
        }
        curr->is_word = true;
    }
    ~TrieNode() {
        for(int i = 0 ; i < 26 ; ++i) 
            delete this->child[i];
    }
};
unordered_map<int, vector<string> > record;
class Solution {
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        TrieNode* root = new TrieNode();
        for(const auto &x : dict) {
            root->insert(x);
        }
        record.clear();
        vector<string>ans =   dfs(s , 0 , root );
        delete root;
        return ans;
    }

    vector<string> dfs(string& s , int start , TrieNode* root ) {
        auto idx = record.find(start);
        if(idx != record.end()) return idx->second;
        vector<string> ans;
        if(start>=s.size()) {
            ans.push_back("-1");
            return ans;
        }
            //break
        TrieNode* curr = root;
        
    
        for(int i = start; i < s.size() ; ++i) {
            if(curr->child[s[i]-'a'] != nullptr) {
                curr = curr->child[s[i]-'a'];
                if(curr->is_word){
                    string word = s.substr(start , i - start + 1);
                    vector<string> tmp = dfs(s , i + 1 , root);
                    if(tmp.size()>0&&tmp.back() == "-1"){
                        ans.push_back(word);
                    }
                    else {
                        for(const auto & x : tmp) {
                            ans.push_back(word + " " + x);
                        }
                    }
                }
            }else break;
        }
        
        record.insert(make_pair(start , ans));
        return ans;
    }
};

 ----------2014.12.19----------

和I一样,用DP算,并记录路径

然后DFS构造答案,代码短很多。

class Solution {
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        vector<string> ans;
        s = "#" + s;
        vector<vector<int> > rec(s.size());
        vector<bool> f(s.size(), false);
        f[0] = true;
        for (int i = 1; i < s.size(); i++) {
            for (int j = 0; j < i; j++) {
                if(f[j] && dict.find(s.substr(j + 1,  i - j)) != dict.end()) {
                    rec[i].push_back(j);
                    f[i] = true;
                }
            }
        }
        dfs(s, ans, "", s.size() - 1, rec);
        return ans;
    }
    void dfs(const string&s, vector<string>& ans, string str, int dep, const vector<vector<int> >& rec) {
        if (dep <= 0) {
            ans.push_back(str.substr(0, str.size()-1));
            return;
        }
        for (int i = 0; i < rec[dep].size(); i++) {
            dfs(s, ans, s.substr(rec[dep][i] + 1, dep - rec[dep][i]) + " " + str, rec[dep][i], rec);
        }
    }
};
原文地址:https://www.cnblogs.com/x1957/p/3528236.html