- 描述:
- 给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict, 判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
- 拆分时可以重复使用字典中的单词。 你可以假设字典中没有重复的单词。
- 示例 示例 1: 输入: s = "applepenapple", wordDict = ["apple", "pen"] 输出: true 解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。 注意你可以重复使用字典中的单词。 示例 2: 输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] 输出: false 示例 3: 输入:"cars", ["car","ca","rs"] 预期:true
-
错误做法
class Solution { public: // 通过测试用例33 / 36 // 没有通过的,比如:"cars" ["car","ca","rs"] // 所以还是用动态规划吧… bool wordBreak(string s, vector<string>& wordDict) { int i,j, flag; //* for(i=0; i<s.size(); i = i+j) { flag=0; for(auto w:wordDict) { for(j=0; j<w.size() && s[i+j]==w[j]; j++); if(j==w.size()) //find word { // i = i+j; flag=1; break; } } if(flag==0) return false; } return true; //*/ } };
-
正确做法:DP。 假设隔断位置是j(下标),mark[j]=true意思是j之前都可以拆分。 初始化:mark[0]=true
- 1 遍历字符串S里每个j,
- 2 遍历j之前所有位置i(前提是i之前可拆分),
- 3 在字典里查找词语S[i:j-1](j-i长度)。如果找到,继续步骤2。
- 4 返回mark[s.size()]
class Solution { public: bool wordBreak(string s, vector<string>& wordDict) { int i,j,k; vector<bool>mark(s.size()+1, false); mark[0]=true; for(j=1; j<=s.size(); j++) // 遍历 隔断位置j { for(i=0; i<j; i++) // 遍历j之前的位置i, 在字典里查找有无j-i长度的词 { if(mark[i]) { for(auto w:wordDict) { // if(w==s.substr(i,j-i)) //这么做浪费空间 // { // mark[j]=true; // break; // } if(j-i==w.size()) { for(k=0; k<w.size() && w[k]==s[i+k]; k++); if(k==w.size()){ mark[j]=true; break; } } } } } } return mark[s.size()]; } };