Word Break II 字符串分割 动态规划+DFS
2015-09-02 16:29
357 查看
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 =
dict =
A solution is
一开始直接用DFS来做,发现超时,思考了一下发现存在重复判断,比如第一次通过两个单词来到位置s[7],DFS后面的字符串无解,第二次通过一个单词直接来到s[7],此时又对后面的字符串进行了DFS,显然是多余的操作。
于是改用动态规划来记录是否有解,再用DFS得出结果。
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"].
一开始直接用DFS来做,发现超时,思考了一下发现存在重复判断,比如第一次通过两个单词来到位置s[7],DFS后面的字符串无解,第二次通过一个单词直接来到s[7],此时又对后面的字符串进行了DFS,显然是多余的操作。
于是改用动态规划来记录是否有解,再用DFS得出结果。
/*2015.9.2cyq*/ #include <iostream> #include <string> #include <vector> #include <unordered_set> using namespace std; //直接DFS,超时 class Solution1{ public: vector<string> wordBreak(string s, unordered_set<string>& wordDict) { vector<string> result; string path; dfs(s,0,wordDict,path,result); return result; } private: void dfs(string &s,int start,unordered_set<string>& wordDict,string &path,vector<string> &result){ if(start==s.size()){ int m=path.size(); result.push_back(path); result.back().resize(m-1); return ; } for(int i=start;i<s.size();i++){ string tmp=s.substr(start,i-start+1); if(wordDict.find(tmp)!=wordDict.end()){ path+=tmp+" "; dfs(s,i+1,wordDict,path,result); path.resize(path.size()-tmp.size()-1); } } } }; //动态规划DP class Solution{ public: vector<string> wordBreak(string s, unordered_set<string>& wordDict) { int n=s.size(); vector<bool> canSolve(n+1,false);//canSolve[i]表示s[i,n-1]可分割成若干个单词 canSolve =true; //f[i][j]表示s[i,j]是一个字典中的单词且canSolve[j+1]=true; vector<vector<bool>> f(n,vector<bool>(n,false)); for(int i=n-1;i>=0;i--){ for(int j=i;j<n;j++){ if(wordDict.find(s.substr(i,j-i+1))!=wordDict.end()&&canSolve[j+1]){ f[i][j]=true; canSolve[i]=true; } } } vector<string> result; string path; dfs(s,0,f,canSolve,path,result); return result; } private: void dfs(string &s,int start,vector<vector<bool>> &f,vector<bool> &canSolve,string &path,vector<string> &result){ if(start==s.size()){ int m=path.size(); result.push_back(path); result.back().resize(m-1); return ; } if(!canSolve[start]) return ;//剪枝 for(int i=start;i<s.size();i++){ if(f[start][i]){ string tmp=s.substr(start,i-start+1); path+=tmp+" "; dfs(s,i+1,f,canSolve,path,result); path.resize(path.size()-tmp.size()-1); } } } }; int main(){ string a[]={"cat","cats","and","sand","dog"}; vector<string> dict(a,a+sizeof(a)/sizeof(string)); unordered_set<string> wordDict; for(int i=0;i<dict.size();i++) wordDict.insert(dict[i]); Solution solu; string s="catsanddog"; vector<string> ret=solu.wordBreak(s,wordDict); for(auto it=ret.begin();it!=ret.end();++it){ cout<<*it<<endl; } return 0; }
相关文章推荐
- 淘宝核心系统团队的产品线
- 旋转链表,递归实现
- Memcached之代理服务magent(8)
- ajax请求json数据案例
- Nodejs express中创建ejs项目
- PAT Advanced 1012
- [转][整理]extern "C"的用法解析
- 【观澜电脑】--XP下CAD打开报错
- jQuery实现带延迟效果的滑动菜单代码
- topcoder powerOutage
- linux学习笔记0.2---gstreamer命令
- java volatile关键字
- [MFC]CDialog类简介、创建模态对话框
- C# 中 SQLite 使用介绍
- 调用
- Java垃圾回收机制
- Io第一天作业
- javascript通用事件封装
- 菜鸟学大数据工具之git
- 面试题汇总