【LeetCode】word break I && II
2014-05-22 10:55
501 查看
参考链接
http://www.cnblogs.com/xinsheng/p/3441044.htmlhttp://www.cnblogs.com/xinsheng/p/3441154.html
http://blog.csdn.net/doc_sgl/article/details/12323015 递归过程中加记忆功能
http://blog.csdn.net/feliciafay/article/details/18999903http://blog.csdn.net/a83610312/article/details/12870501 这个思路和上面的略不一样
题目描述
Word Break
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".
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"].
题目分析
思路:1. DFS 搜索会 TLE
2. 改用 DP, 思路与 word palindrome 一样, iteration based dp
3. bool dp[i] 表示从 i...s.size() 是否匹配
总结:
1. DP 解法中, 设置 dp[s.size()] = true 相当于初始条件
代码示例
class Solution { public: bool dp[1000]; bool wordBreak(string s, unordered_set<string> &dict) { memset(dp, false, sizeof(dp)); if(s.size() == 0 ) return true; dp[s.size()] = true; for(int i = s.size()-1; i >= 0; i --) { int len1 = s.size() - i; for(unordered_set<string>::iterator it_set = dict.begin(); it_set != dict.end(); it_set++) { int len2 = it_set->size(); if(len1 >= len2 && dp[i] == false) { if(dp[i+len2] && s.substr(i, len2)==*it_set) { dp[i] = true; break; } } } } return dp[0]; } };上面那个示例是遍历字典进行匹配。复杂度为O(s.size*dict.size)
下面的是先取子串再去字典中匹配。
class Solution { public: bool wordBreak(string s, unordered_set<string> &dict) { //bool wordBreak(string s, set<string> &dict) { vector<bool> dp(s.size()+1,false); dp[0] = true; for(int i = 1;i<=s.size();i++) { if(dp[i-1]) { int idx = i-1; for(int j = idx;j<s.size();j++) { string str = s.substr(idx,j-idx+1); if(dict.find(str) != dict.end()) dp[j+1] = true; } } } return dp[s.size()]; } };
1. dp + 打印路径
2. dfs + 打印路径 是非常直接的, 设置一个全局变量记录当前路径, 当 dfs 到最后一步时输出该全局变量即可. 实现时要注意全局变量的 do 和 undo 操作. word break 使用 dfs 搜索超时了, 我就没用 dfs + 打印路径的方法来求解 word break II
3. word break II 是在前一题的基础上加上路径打印即可. 我仍然使用了上一题的代码, 稍作修改. 加上了一个 vector<string> record[1000], 这个变量记录可以使 dp[i] 为 true 的单词. 最后用一个 dfs 把这些单词摘下来组成句子
总结:
1. 第一次做 dp + 打印路径. 以前总是用搜索+打印路径来做类似的题目
2. 明显的搜索问题应当优先考虑 DP 解法
class Solution {
public:
//vector<string> wordBreak(string s, unordered_set<string> &dict) {
vector<string> wordBreak(string s, set<string> &dict) {
int size = s.size();
vector<string> ret;
vector<vector<string> > vec(size,vector<string>());
vector<bool> dp(s.size()+1,false);
//printf("%d\n",vec.size());
dp[0] = true;
for(int i = 1;i<=s.size();i++)
{
//printf("%d-%d\n",i-1,(int)dp[i-1]);
if(dp[i-1])
{
int idx = i-1;
for(int j = idx;j<s.size();j++)
{
string str = s.substr(idx,j-idx+1);
if(dict.find(str) != dict.end())
{
dp[j+1] = true;
vec[idx].push_back(str);//////////////////////////////
}
}
}
}
//printf("%d-%d\n",s.size(),(int)dp[s.size()]);
if(dp[s.size()])
{
string tmp;
DFS(ret,vec,0,"",s);
}
return ret;
}
void DFS(vector<string> &ret,vector<vector<string> > &vec,int idx,string tmp,const string &s)//tmp不能使用引用
{
//printf("idx = %d-------------%d\n",idx,s.size());
if(idx == s.size())
{
//cout<<"tmp = "<<tmp<<endl;
tmp.erase(tmp.size()-1,1);//去除最后一个空格
//cout<<"tmp = "<<tmp<<endl;
ret.push_back(tmp);///////////////////tmp不能使用引用
return;
}
else if(idx > s.size())
return;
for(int i = 0;i<vec[idx].size();i++)
{
//cout<<vec[idx][i]<<endl;
int len = vec[idx][i].size();
tmp = tmp + vec[idx][i] + " ";
DFS(ret,vec,idx+len,tmp,s);
tmp.erase(tmp.size()-len-1,len+1);
}
}
};
推荐学习C++的资料
C++标准函数库http://download.csdn.net/detail/chinasnowwolf/7108919
在线C++API查询
http://www.cplusplus.com/
相关文章推荐
- LeetCode Word Break & Word Break II
- LeetCode ||& Word Break && Word Break II(转)——动态规划
- LeetCode: Word Break I && II
- 【LeetCode】Word Break && Word Break II
- 【leetcode】Word Break && Word Break II
- Leetcode 139&140. Word Break I & II
- leetcode word break I && II
- Leetcode 139. Word Break & 140. Word Break II
- Leetcode 139. Word Break I&&II
- LeetCode之“动态规划”:Word Break && Word Break II
- leetcode做题总结,回溯法(N-Queens, N-QueensII,Combination SumI&II,wordbreak II, SubsetsI&II)
- leetCode: Word Break I & Word Break II
- [Leetcode]Word Break & Word Break II
- [LeetCode] Word Break && Word Break II
- [C++]LeetCode: 113 Word Break II (DP && Backtacking) 求解拆分组合
- leetcode -- Word Break I & II -- 重点
- leetcode Word Break I II 算法分析
- LeetCode - Word Break II
- Leetcode Word Break II
- [LeetCode] - Word Break II