Word Break II 解答

Question

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"].

Solution

这题的基本思路是用recursion,每次都只研究第一刀切在哪儿,然后对剩下的substring做递归。但是我们发现其实可以借助DP的思想,存下来部分中间结果值。这种思想也叫 Memorized Recursion

Memorized recursion并不是一个很好的方法,但是当遇到time limit exceed时可以想到它来拿空间换时间

 1 class Solution:
 2     # @param s, a string
 3     # @param dict, a set of string
 4     # @return a list of strings
 5     def wordBreak(self, s, dict):
 6         self.dict = dict
 7         # cache stores tmp results: key: substring value: list of results
 8         self.cache = {}
 9         return self.break_helper(s)
10 
11     def break_helper(self, s):
12         combs = []
13         if s in self.cache:
14             return self.cache[s]
15         if len(s) == 0:
16             return []
17 
18         for i in range(len(s)):
19             if s[:i+1] in self.dict:
20                 if i == len(s) - 1:
21                     combs.append(s[:i+1])
22                 else:
23                     sub_combs = self.break_helper(s[i+1:])
24                     for sub_comb in sub_combs:
25                         combs.append(s[:i+1] + ' ' + sub_comb)
26 
27         self.cache[s] = combs
28         return combs

第二种思路:先用DP,再用DFS

dp[i] 为list<String>表示以i结尾的在word dict中的词,并且满足dp[i - wordLen]不是null。

DFS从dp[len]开始,遍历可能的词。

 1 public class Solution {
 2     public List<String> wordBreak(String s, Set<String> wordDict) {
 3         List<String> result = new ArrayList<>();
 4         if (wordDict == null || s == null) {
 5             return result;
 6         }
 7         int len = s.length();
 8         ArrayList<String>[] dp = new ArrayList[len + 1];
 9         dp[0] = new ArrayList<String>();
10         for (int i = 0; i < len; i++) {
11             if (dp[i] != null) {
12                 for (int j = i + 1; j <= len; j++) {
13                     String sub = s.substring(i, j);
14                     if (wordDict.contains(sub)) {
15                         if (dp[j] == null) {
16                             dp[j] = new ArrayList<String>();
17                         }
18                         dp[j].add(sub);
19                     }
20                 }
21             }
22         }
23         if (dp[len] == null) {
24             return result;
25         }
26         // dfs
27         dfs(dp, result, "", len);
28         return result;
29     }
30     
31     private void dfs(ArrayList<String>[] dp, List<String> result, String tail, int curPos) {
32         if (curPos == 0) {
33             result.add(tail.trim());
34             return;
35         }
36         for (String str : dp[curPos]) {
37             String curStr = str + " " + tail;
38             dfs(dp, result, curStr, curPos - str.length());
39         }
40     }
41 }

 

posted @ 2015-11-02 03:28  树獭君  阅读(238)  评论(0编辑  收藏  举报