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