给定一个非空字符串 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
class Solution {
private:
unordered_map<string,int> dict;
bool dictbreak(string s)
{
if(dict[s]) return true;
for(int i=1;i<s.length();i++)
{
string tmp=s.substr(0,i);
if(dict[tmp] && dictbreak(s.substr(i,s.length()-i)))
return true;
}
return false;
}
public:
bool wordBreak(string s, vector<string>& wordDict) {
for(int i=0;i<wordDict.size();i++)
dict[wordDict[i]]++;
return dictbreak(s);
}
};
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
unordered_set<string> dict(wordDict.cbegin(),wordDict.cend());
return wordBreak(s,dict);
}
bool wordBreak(string s, const unordered_set<string>& wordDict) {
if(mem.count(s)) return mem[s];
if(wordDict.count(s)) return mem[s]=true;
for(int i=0;i<s.length();i++)
{
const string left=s.substr(0,i);
const string right=s.substr(i);
if(wordDict.count(right) && wordBreak(left,wordDict))
return mem[s]=true;
}
return mem[s]=false;
}
private:
unordered_map<string,bool> mem;
};
class Solution {
public:
bool wordBreak(string s, vector<string>& wordDict) {
if(s.empty()){
return true;
}
for(auto s:wordDict){
wordset.insert(s);
if(s.size()>maxl){
maxl=s.size();
}
}
vector<bool>flag(s.size()+1,false);
flag[0]=true;
for(int i=0;i<s.size();i++){
for(int j=0;j<min(maxl,i+1);j++){
if(flag[i-j]&&(wordset.find(s.substr(i-j,j+1))!=wordset.end())){
flag[i+1]=true;
break;
}
}
}
return flag[s.size()];
}
private:
unordered_set<string> wordset;
int maxl=0;
};