给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
**说明:
- 拆分时可以重复使用字典中的单词。
- 你可以假设字典中没有重复的单词。**
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。
输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
注意你可以重复使用字典中的单词。
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false
第一次尝试(Trie树 会TLE):
class Solution {
public:
int son[100010][26], idx=0;
bool cnt[100010];
bool wordBreak(string s, vector<string>& wordDict) {
for(int i=0;i<100010;i++)
for(int j=0;j<26;j++)
son[i][j]=0;
for(int i=0;i<100010;i++){
cnt[i]=false;
}
for(int i=0;i<wordDict.size();i++){
string str=wordDict[i];
int p = 0;
for (int j = 0; str[j]; j ++ )
{
int u = str[j] - 'a';
if (!son[p][u]) son[p][u] = ++ idx;
p = son[p][u];
}
cnt[p]=true;
}
return judge(s);
}
bool judge(string& s){
if(s=="")
return true;
for(int i=1;i<=s.size();i++){
string p=s.substr(0,i);
if(!query(p))
continue;
string q=s.substr(i,s.size()-i);
if(judge(q))
return true;
}
return false;
}
bool query(string& str)
{
int p = 0;
for (int i = 0; str[i]; i ++ )
{
int u = str[i] - 'a';
if (!son[p][u]) return false;
p = son[p][u];
}
return cnt[p];
}
};
第二次尝试(DP):
class Solution {
public:
bool f[100010];
bool wordBreak(string s, vector<string>& wordDict) {
f[0]=true;
for(int i=1;i<=s.size();i++){
bool flag=false;
for(int j=1;j<=i;j++){
string t=s.substr(i-j,j);
if(f[i-j]&&find(wordDict.begin(),wordDict.end(),t)!=wordDict.end())
{
flag=true;
break;
}
}
f[i]=flag;
}
return f[s.size()];
}
};