给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
这里的位置划分明显有两个变量 i 和 j
有 0 < j <= i
分析 i 位置的状态转移方程
dp[i] =
if (dp[j] == true &&
s.substr(j, i-j) 在 wordDict 中), true
else, false
🐎 代码如下:
(下面还有优化版本)
class Solution {
public:
bool IsInDict(const string& str, const vector<string>& wordDict)
{
for(auto e : wordDict)
{
if (str == e)
{
return true;
}
}
return false;
}
bool wordBreak(string s, vector<string>& wordDict) {
int n = s.size();
vector<int> dp(n + 1);
dp[0] = 1;
s = 'x' + s;
for(int i = 1; i < n + 1; i++)
{
for(int j = 1; j <= i; j++)
{
if(dp[j-1] == 1 && IsInDict(s.substr(j, i-j+1), wordDict))
{
dp[i] = 1;
break;
}
}
}
return dp[n];
}
};
…
…
这里 IsInDict 的实现是不是有点傻?字典查询,属于“在不在”问题,用 hash 怎么样~
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> hash;
for(auto e : wordDict) hash.insert(e);
int n = s.size();
vector<bool> dp(n + 1); // bool在vector中默认值是0,跟int一样啦
dp[0] = true; // 保证后续结果正确
s = 'x' + s; // 保持统一,方便读取原数据
for(int i = 1; i < n + 1; i++)
{
for(int j = 1; j <= i; j++)
{
if(dp[j-1] == 1 && hash.count((s.substr(j, i-j+1))))
{
dp[i] = true;
break;
}
}
}
return dp[n];
}
};
🥰如果本文对你有些帮助,欢迎👉 点赞 收藏 关注,你的支持是对作者大大莫大的鼓励!!(????) 若有差错恳请留言指正~~