单词拆分
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:
拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:
输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以被拆分成 “leet code”。
示例 2:
输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以被拆分成 “apple pen apple”。
注意你可以重复使用字典中的单词。
示例 3:
输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false
思路和代码
动态规划的思路:dp[i]表示前i个字符是否可以拆分,要想求得dp[i],只要对于任意的 j ,存在 j 小于 i ,并且dp[ j ]和s.substr(j, i-j)都在字典中即可。
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
vector<bool> dp(s.size() + 1);
dp[0] = true;
for (int i = 0; i < dp.size(); ++i) {
for (int j = 0; j < i; ++j) {
if (dp[j] && wordSet.count(s.substr(j, i - j))) {
dp[i] = true;
break;
}
}
}
return dp.back();
}
};
单词拆分2
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,在字符串中增加空格来构建一个句子,使得句子中所有的单词都在词典中。返回所有这些可能的句子。
说明:
分隔时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:
输入:
s = “catsanddog”
wordDict = [“cat”, “cats”, “and”, “sand”, “dog”]
输出:
[
“cats and dog”,
“cat sand dog”
]
示例 2:
输入:
s = “pineapplepenapple”
wordDict = [“apple”, “pen”, “applepen”, “pine”, “pineapple”]
输出:
[
“pine apple pen apple”,
“pineapple pen apple”,
“pine applepen apple”
]
解释: 注意你可以重复使用字典中的单词。
思路和代码
一看是求所有解,那就是递归,这里用哈希来保存一个字符串对应的所有划分结果。
参考链接
class Solution {
public:
vector<string> wordBreak(string s, vector<string>& wordDict) {
map<string, vector<string>> m;
return core(s, wordDict, m);
}
vector<string> core(string s, vector<string>& wordDict, map<string, vector<string>>& m){
if(m.count(s))
return m[s];//哈希表已经有s对应的所有划分的字符串数组,那么直接返回
if(s.empty())
return {""};
vector<string> res;
for(string word : wordDict){
if(s.substr(0, word.size()) != word)
continue;
vector<string> temp = core(s.substr(word.size()), wordDict, m);
for(string str: temp){
res.push_back(word + (str.empty() ? "" : " ") + str);
}
}
return m[s] = res;
}
};