LintCode 107: Word Break (DFS, DP經典題!)

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

Example
Given s = “lintcode”, dict = [“lint”, “code”].

Return true because “lintcode” can be break as “lint code”.

解法1:DFS。超時 (95%的時候)

class Solution {
public:
    /*
     * @param s: A string
     * @param dict: A dictionary of words dict
     * @return: A boolean
     */
    bool wordBreak(string &s, unordered_set<string> &dict) {
        int lenS = s.size();
        int lenD = dict.size();
        maxWordLen = 0;
        minWordLen = lenS;
        
        for (auto w : dict) {
            maxWordLen = max(maxWordLen, (int)w.size());
            minWordLen = min(minWordLen, (int)w.size());
        }
        
        vector<string> sol;
        vector<vector<string>> result;
        
        helper(s, dict, sol, result);
        if (result.size() > 0) return true;
        return false;
    }
    
private:

    void helper(string &s, unordered_set<string> &dict, vector<string> &sol, vector<vector<string>> &result) {
        
        int len = s.size();
        if (len == 0) {
            result.push_back(sol);
            return;
        }
        if (len < minWordLen) 
            return;
        
        for (int i = minWordLen; i <= maxWordLen; ++i) {
            string w = s.substr(0, i);
            if (dict.find(w) == dict.end()) continue;
            sol.push_back(w);
            string newStr = s.substr(i, len - i);
            helper(newStr, dict, sol, result);
            sol.pop_back();
        }
    }
    
    int minWordLen;
    int maxWordLen;
};

解法2:還是DFS,s不動index動。Pass。

class Solution {
public:
    /*
     * @param s: A string
     * @param dict: A dictionary of words dict
     * @return: A boolean
     */
    bool wordBreak(string &s, unordered_set<string> &dict) {
        int lenS = s.size();
        int lenD = dict.size();
        maxWordLen = 0;
        minWordLen = lenS;
        
        for (auto w : dict) {
            maxWordLen = max(maxWordLen, (int)w.size());
            minWordLen = min(minWordLen, (int)w.size());
        }
        
        vector<string> sol;
        vector<vector<string>> result;
        
        helper(s, 0, dict, sol, result);
        if (result.size() > 0) return true;
        return false;
    }
    
private:

    void helper(string &s, int index, unordered_set<string> &dict, vector<string> &sol, vector<vector<string>> &result) {
        
        int len = s.size();
        if (index == len) {
            result.push_back(sol);
            return;
        }
        
        if (index + minWordLen > len)    //剪枝
            return;
        
        for (int i = minWordLen; i <= maxWordLen; ++i) {
            string w = s.substr(index, i);
            if (dict.find(w) == dict.end()) continue;
            sol.push_back(w);
            helper(s, index + i, dict, sol, result);
            sol.pop_back();
        }
    }
    
    int minWordLen;
    int maxWordLen;
};

解法3:DFS+Memorization
即把s分成str1和str2,如果str1在dict中則可調用子問題,輸入爲str2。
Memozation可以減枝。
代碼如下:

class Solution {
public:
    /*
     * @param s: A string
     * @param dict: A dictionary of words dict
     * @return: A boolean
     */
    bool wordBreak(string &s, unordered_set<string> &dict) {
        if (s.size() == 0 && dict.size() == 0) return true;
        unordered_map<string, bool> memo;
        return helper(s, dict, memo);
    }
    
private:
    bool helper(string &s, unordered_set<string> &dict, unordered_map<string, bool> & memo) {
        if (s.size() == 0) return false;
        if (memo.find(s) != memo.end()) return memo[s];
        
        int len = s.size();
        for (int i = 1; i <= len; ++i) {
            string subStr1 = s.substr(0, i);
            
            if (dict.find(subStr1) != dict.end()) {
                if (subStr1 == s) {
                    memo[s] = true;
                    return true;
                }
                string subStr2 = s.substr(i);
                bool result = helper(subStr2, dict, memo);
                if (result) {
                    memo[s] = true;    
                    return true;
                }
            }
        }
        memo[s] = false;
        return false;
    }
   
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章