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"
.
才发现我一直把题意理解错了,原来是源串分出来的词只要都在字典里就好了,比如leetleet就可以分成两个leet都在词典里,原来不是所有字典里的词都要出现。
那就容易些了,另dp[i] 表示源串的前i个字符可以满足分割,那么 dp[ j ] 满足分割的条件是存在k 使得 dp [k] && substr[k,j]在字典里。
这是O(n2)的算法,注意下标,因为很恶心。
class Solution { public: bool wordBreak(string s, unordered_set<string> &dict) { // Note: The Solution object is instantiated only once and is reused by each test case. int n = (int)s.size(); vector<bool> dp(n + 1, false); dp[0]=true; for(int i=1;i<=n;i++) { if(dp[i-1]) { int idx=i-1; for(int j=idx;j<n;j++) { string cur=s.substr(idx,j-idx+1); if(dict.count(cur)>0) dp[j+1]=true; } } } return dp[n]; } };
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"]
.
跟第一题一样,就是要返回所有可能的切分, 做切分反应是用回溯,但是不剪枝肯定要超时。
这里用了一个math[i][j] 来表示 i--j 这一段是否可以切分,然后在dfs的时候利用看最后剩余的子串能否切分来剪枝。
class Solution { public: vector<string> wordBreak(string s, unordered_set<string> &dict) { int n=s.length(); vector<vector<bool> > match(n+1,vector<bool>(n+1,false)); for(int i=0;i<=n;i++) match[0][i]=true; for(int len=1;len<=n;len++) { for(int start=0;start+len<=n;start++) { string tmp=s.substr(start,len); if(dict.count(tmp)>0) match[len][start]=true; else { for(int left=1;left<len;left++) { match[len][start]=match[left][start]&&match[len-left][start+left]; if(match[len][start]) break; } } } } if(match[n][0]==false) return vector<string>(); vector<string> ans; vector<string> had; dfs(s,0,match,had,ans,dict); return ans; } void dfs(string& s,int k,vector<vector<bool> >& match,vector<string>& had,vector<string>& ans,unordered_set<string> &dict) { int n=s.length(); if(k>=n) { if(!had.empty()) { string ret; for(int i=0;i<had.size();i++) { ret.append(had[i]); if(i!=had.size()-1) ret.push_back(' '); } ans.push_back(ret); return; } } for(int len=1;k+len<=n;len++) { string tmp=s.substr(k,len); if(dict.count(tmp)>0 && match[n-k-len][k+len]) { had.push_back(tmp); dfs(s,k+len,match,had,ans,dict); had.pop_back(); } } } };