天天看點

[Leetcode] 139. Word Break 解題報告

題目:

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words. You may assume the dictionary does not contain duplicate words.

For example, given

s = 

"leetcode"

,

dict = 

["leet", "code"]

.

Return true because 

"leetcode"

 can be segmented as 

"leet code"

.

思路:

這也是一道動态規劃題目,不過遞推式有點隐晦。我們定義dp[i]表示字元串的前i個字元是否可以用字典中的單詞構成,那麼其遞推式為:如果存在0 <= j <= i,滿足dp[j]為true,并且s中從j到i構成的子字元串存在于字典中,那麼dp[i]為true;否則dp[i]為false。注意我們在第二重循環中讓j從大往小循環是為了提高效率:一旦大的j已經可以滿足條件,就可以提前跳出了,而不必再測試小的j,這就充分利用了子問題的結論。該算法的時間複雜度為O(n^2),空間複雜度為O(n)。

代碼:

class Solution {
public:
    bool wordBreak(string s, unordered_set<string>& wordDict) {
        vector<bool> dp(s.length() + 1, false);
        dp[0] = true;
        for(int i = 0; i < s.length(); ++i) {
            for(int j = i; j >= 0; --j) {
                // from[0,j - 1] it can be broken, and from [j, i] is in the wordDict
                if(dp[j] && wordDict.count(s.substr(j, i - j + 1)) > 0) {
                    dp[i + 1] = true;
                    break;
                }
            }
        }
        return dp[s.length()];
    }
};