Solution 1
一看就是动态规划没跑了……
子结构 d p [ i ] dp[i] dp[i]:从头到当前位置 i − 1 i-1 i−1的子串是否符合要求(由dict中的单词连接构成)
状态转移:(any型)这个子串存在一个切分点 j j j, d p [ j ] dp[j] dp[j]满足要求且子串 j … i − 1 j\ldots i-1 j…i−1满足要求
初始化: d p [ 0 ] dp[0] dp[0]空串,满足要求
需要注意:枚举情况下在子串判定上简化时间(哈希表)
- 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n n n为字符串的长度,完全遍历的情况下的中间子串枚举
- 空间复杂度: O ( n ) O(n) O(n),动态规划数组占用
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
int len = s.size();
unordered_set<string> wordDictSet;
for (auto word: wordDict) {
wordDictSet.insert(word);
}
auto ans = vector<bool> (len + 1);
ans[0] = true;
for (int i = 1; i <= len; ++i) {
for (int j = 0; j < i; ++j) {
if (ans[j] && wordDictSet.find(s.substr(j, i - j)) != wordDictSet.end()) {
ans[i] = true;
break;
}
}
}
return ans[len];
}
};
Solution 2
Solution 1的Python实现
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
length = len(s)
wordDictSet = set()
for word in wordDict: wordDictSet.add(word)
ans = [False] * (length + 1)
ans[0] = True
for i in range(1, length + 1):
for j in range (i):
if ans[j] and s[j:i] in wordDictSet:
ans[i] = True
break
return ans[length]