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):
让我们来继续切切切吧!

本题与上一题Word Break思路类似,但是一个是DP,一个是DFS。
让我们来回顾一下DP与DFS的区别:
DP是Bottom-up 而DFS是TOP-DOWN.

在本题的DFS中,我们这样定义:
用刀在字符串中切一刀。左边是i个字符,右边是len-i个字符。
i: 1- len
如果: 左边是字典里的词,右边是可以wordbreak的,那么把左边的字符串加到右边算出来的List中,生成新的list返回。
1. Base case:
当输入字符串为空的时候,应该给出一个空解。这个很重要,否则这个递归是不能运行的。
2. 递归的时候,i应该从1开始递归,因为我们要把这个问题分解为2个部分,如果你左边给0,那就是死循环。

记忆:
为了加快DFS的速度,我们应该添加记忆,也就是说,算过的字符串不要再重复计算。举例子:
apple n feng
app len feng
如果存在以上2种划分,那么feng这个字符串会被反复计算,在这里至少计算了2次。我们使用一个Hashmap把对应字符串的解记下来,这样就能避免重复的计算。 否则这一道题目会超时。

 1 // 我们用DFS来解决这个问题吧 
 2     public static List<String> wordBreak1(String s, Set<String> dict) {
 3         HashMap<String, List<String>> map = new HashMap<String, List<String>>();
 4         if (s == null || s.length() == 0 || dict == null) {
 5             return null;
 6         }
 7 
 8         return dfs(s, dict, map);
 9     }
10 
11     // 解法1:我们用DFS来解决这个问题吧 
12     public static List<String> dfs(String s, Set<String> dict, HashMap<String, List<String>> map) {
13         if (map.containsKey(s)) {
14             return map.get(s);
15         }
16 
17         List<String> list = new ArrayList<String>();
18         int len = s.length();
19 
20         if (len == 0) {
21             list.add("");
22         } else {
23             // i 表示左边字符串的长度
24             for (int i = 1; i <= len; i++) {
25                 String sub = s.substring(0, i);
26 
27                 // 左边的子串可以为空,或是在字典内
28                 if (!dict.contains(sub)) {
29                     continue;
30                 }
31 
32                 // 字符串划分为2边,计算右边的word break.
33                 List<String> listRight = dfs(s.substring(i, len), dict, map);
34 
35                 // 右边不能break的时候,我们跳过.
36                 if (listRight.size() == 0) {
37                     continue;
38                 }
39 
40                 // 把左字符串加到右字符串中,形成新的解.
41                 for (String r: listRight) {
42                     StringBuilder sb = new StringBuilder();
43                     sb.append(sub);
44                     if (i != 0 && i != len) {
45                         // 如果左边为空,或是右边为空,不需要贴空格
46                         sb.append(" ");
47                     }
48                     sb.append(r);
49                     list.add(sb.toString());
50                 }
51             }
52         }
53 
54         map.put(s, list);
55         return list;
56     }
View Code

相关文章: