Word Break I, II
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode"
,
dict = ["leet", "code"]
.
Return true because "leetcode"
can be segmented as "leet code"
.
一个DP问题。定义possible[i] 为S字符串上[0,i]的子串是否可以被segmented by dictionary.
那么
possible[i] = true if S[0,i]在dictionary里面
= true if possible[k] == true 并且 S[k+1,i]在dictionary里面, 0<k<i
= false if no such k exist.
1 class Solution { 2 public: 3 bool wordBreak(string s, unordered_set<string> &dict) { 4 int len=s.size(); 5 vector<int> inDict (len,0); 6 int pre=0; 7 for(int i=0;i<len;i++) 8 { 9 10 if(dict.find(s.substr(0,i+1))!=dict.end()) 11 { 12 inDict[i]=1; 13 continue; 14 } 15 for(int j=i;j>=0;j--)//start from the end; 16 { 17 if(inDict[j]==1) 18 { 19 if(dict.find(s.substr(j+1,i-j))!=dict.end())//!!!j+1,i-j 20 { 21 inDict[i]=1; 22 break; 23 } 24 } 25 } 26 27 28 } 29 30 if(inDict[len-1]==1) return true; 31 else return false; 32 33 } 34 };
Word Break II
Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.
Return all such possible sentences.
For example, given
s = "catsanddog"
,
dict = ["cat", "cats", "and", "sand", "dog"]
.
A solution is ["cats and dog", "cat sand dog"]
.
思路:递归,加及时剪枝。
这里加上一个possible数组,如同WordBreak I里面的DP数组一样,用于记录区间拆分的可能性
Possible[i] = true 意味着 [i,n]这个区间上有解
加上剪枝以后,运行时间就大大减少了。
还有就是循环中的递归。
1 class Solution { 2 public: 3 vector<string> wordBreak(string s, unordered_set<string> &dict) { 4 vector<string> res; 5 vector<bool> pos(s.size(),true);//用于剪枝的数组 6 string result; 7 process(s,0,s.size(),dict,result,res,pos); 8 return res; 9 } 10 void process(string& s, int start, int len, unordered_set<string> &dict, string& result, vector<string> &res, vector<bool>& pos) 11 { 12 if(start==len) 13 { 14 res.push_back(result.substr(0,result.size()-1));//去除最后一个空格 15 return; 16 } 17 18 for(int i=start;i<len;i++) 19 { 20 string temp=s.substr(start, i-start+1); 21 if(dict.find(temp)!=dict.end()&&pos[i])//剪枝 22 { 23 result=result.append(temp).append(" "); 24 int pre=res.size(); 25 process(s,i+1,len,dict,result,res,pos); 26 if(res.size()==pre) 27 pos[i]=false;//记录后面计算可以用于剪枝的信息 28 result.resize(result.size()-temp.size()-1);//通过resize恢复字符串 29 } 30 } 31 32 } 33 };