題目:
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()];
}
};