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 };

 

posted @ 2014-07-08 14:14  Hicandyman  阅读(125)  评论(0编辑  收藏  举报