给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> ust(wordDict.begin(), wordDict.end());
int n = s.size(), minLen = INT_MAX, maxLen = 0;
bool dp[n + 1]; memset(dp, 0, sizeof dp);
dp[0] = 1;
for (string& w : wordDict) { // 用于剪枝
minLen = min(minLen, (int)w.size());
maxLen = max(maxLen, (int)w.size());
}
for (int i = minLen; i <= n; i++) {
for (int j = max(0, i - maxLen); j <= i - minLen; j++) {
if (ust.find(s.substr(j, i - j)) != ust.end() && dp[j]) {
dp[i] = 1;
break;
}
}
}
return dp[n];
}
};
本题可以看做一道完全背包问题,也就是字典中元素为物品,s
为背包。但是我觉得这道题看做字符串的动态规划比较直观。dp[i]
表示从角标0出发,以角标i
结尾的字符串是否能被字典中的单词拆分。本题做了剪枝操作,提升效果较为明显,从24ms提升至0ms。
原文:https://www.cnblogs.com/tmpUser/p/14611790.html