LintCode: Word Break

给定字符串序列和一个字典,问给定的字符串能否用字典中的单词拼出来?

图:

  节点:字符串的前缀长度

  边:前缀x如果加一个字典里边的单词能形成新前缀x',则有一条边

    例如:字符串IAMxxxxx,字典里有I和AM

    则有(0,1)一条边,(1,3)一条边

解:从(0,?)到(?,n)找一条路径

这是一个判断是否有解的问题

BFS/DFS

  从当前前缀开始加一个单词

其他

  能否dp?bool dp[x]表示能否连到x位置

  dp[x] = dp[y] && (y..x是一个单词)

思考:

  如何求一组解?全部解?

C++ 

DFS

(lintcode: s太长的话,会溢出。64bit mac OS上字符串长度超过8881就溢出。)

(leetcode: Accepted)

复制代码
 1 class Solution {
 2 public:
 3     bool help(string &s, int now, unordered_set<string> &d, vector<bool> &have) {
 4         if (now >= s.length()) {
 5             return true;
 6         }
 7         if (have[now]) {
 8             return false;
 9         }
10         have[now] = true;
11         for (int i = now; i < s.length(); ++i) {
12             if ((d.find(s.substr(now, i - now + 1)) != d.end()) && (help(s, i + 1, d, have))) {
13                 return true;
14             }
15         }
16         return false;
17     }
18     /**
19      * @param s: A string s
20      * @param dict: A dictionary of words dict
21      */
22     bool wordBreak(string s, unordered_set<string> &dict) {
23         // write your code here
24         vector<bool> have(s.length(), false);
25         return help(s, 0, dict, have);
26     }
27 };
复制代码

C++

BFS

(lintcode:字符串太长,例如超过10000个字符,会超时)

(leetcode: Accepted)

复制代码
 1 class Solution {
 2 public:
 3     bool help(string &s, unordered_set<string> &d) {
 4         if (0 == s.length()) {
 5             return true;
 6         }
 7         vector<bool> have(s.length(), false);
 8         have[0] = true;
 9         queue<int> q;
10         for (q.push(0); !q.empty(); q.pop()) {
11             int now = q.front();
12             for (int i = now; i < s.length(); ++i) {
13                 if ((d.find(s.substr(now, i - now + 1)) != d.end())) {
14                     if (i + 1 >= s.length()) {
15                         return true;
16                     }
17                     if (!have[i + 1]) {
18                         have[i + 1] = true;
19                         q.push(i + 1);
20                     }
21                 }
22             }
23         }
24         
25         return false;
26     }
27     /**
28      * @param s: A string s
29      * @param dict: A dictionary of words dict
30      */
31     bool wordBreak(string s, unordered_set<string> &dict) {
32         // write your code here
33         return help(s, dict);
34     }
35 };
复制代码

C++

DP

(lintcode:字符串太长,例如超过10000个字符,会超时)

(leetcode: Accepted)

复制代码
 1 class Solution {
 2 public:
 3     bool help(string &s, unordered_set<string> &d) {
 4         if (0 == s.length()) {
 5             return true;
 6         }
 7         vector<bool> dp(s.length(), false);
 8         dp[0] = true;
 9         for (int now = 0; now < s.length(); ++now) {
10             if (!dp[now]) {
11                 continue;
12             }
13             for (int i = now; i < s.length(); ++i) {
14                 if ((d.find(s.substr(now, i - now + 1)) != d.end())) {
15                     if (i + 1 >= s.length()) {
16                         return true;
17                     }
18                     dp[i + 1] = true;
19                 }
20             }
21         }
22         
23         return false;
24     }
25     /**
26      * @param s: A string s
27      * @param dict: A dictionary of words dict
28      */
29     bool wordBreak(string s, unordered_set<string> &dict) {
30         // write your code here
31         return help(s, dict);
32     }
33 };
复制代码

 Python

DP

复制代码
 1 class Solution:
 2     # @param s: A string s
 3     # @param dict: A dictionary of words dict
 4     def wordBreak(self, s, dict):
 5         if len(dict) == 0:
 6             return len(s) == 0
 7             
 8         n = len(s)
 9         f = [False] * (n + 1)
10         f[0] = True
11         
12         maxLength = max([len(w) for w in dict])
13         for i in xrange(1, n + 1):
14             for j in range(1, min(i, maxLength) + 1):
15                 if not f[i - j]:
16                     continue
17                 if s[i - j:i] in dict:
18                     f[i] = True
19                     break
20         
21         return f[n]
复制代码

 

本文转自ZH奶酪博客园博客,原文链接:http://www.cnblogs.com/CheeseZH/p/5012413.html,如需转载请自行联系原作者

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值