[leecode]Word Break II

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

建议做这道题的时候先看下[leetcode]Word Break

算法思路:

1. 同[leetcode]Word Break,从每一个index遍历字典,找到可以跳达的下标cover[index];不过本地在维护一个map,记录该下标是从哪个下标跳过来的。可能是个list。例如题目中的index = 6 ,可以从下标为2,和3 跳过来。

2.1. 如果cover[length - 1] = false,则表示不可拆分,直接返回一个空list;

2.2  如果length可达,那么好了,根据map可以建立一个树,这个树的根节点肯定是length,叶节点肯定是0,因为无论怎么个跳法,最后一个下标总是从第一个下标跳过来的。

例如题目中的s=“catsanddog”

[leetcode]Word Break,我们从1开始记录。

最后一个字符g的下标为10.10的前驱是sand中的d->7,而7的前驱是3 & 4,3 & 4 的前驱都是0;

因此这棵树的结构应该是这样的。

                  10

                   |

                   7

                /     \

              3         4

            /              \

          0                 0

因此我们就可以用dfs,将结果返回。

代码如下:

 1 public class Solution {
 2     List<String> res = new ArrayList<String>();
 3     public List<String> wordBreak(String s, Set<String> dict) {
 4         if(s == null || s.length() == 0) return res;
 5         Map<Integer,List<Integer>> pre = new HashMap<Integer,List<Integer>>();
 6         int length = s.length();
 7         boolean[] cover = new boolean[length + 1];
 8         cover[0] = true;
 9         for(int i = 0; i <= length; i++){
10             if(!cover[i]) continue;
11             for(String word: dict){
12                 if(s.substring(i).startsWith(word)){
13                     int stretch = i + word.length();
14                     if(!cover[stretch]){
15                         cover[stretch] = true;
16                         List<Integer> list = new ArrayList<Integer>();
17                         list.add(i);
18                         pre.put(stretch,list);
19                     }else{
20                         pre.get(stretch).add(i);
21                     }
22                 }
23             }
24         }
25         if(!cover[length]) return res;
26         List<String> list = new LinkedList<String>();
27         getList(list,length,s,pre);
28         return res;
29     }
30     private void getList(List<String> list,int index,String s,Map<Integer,List<Integer>> preMap){
31         if(index == 0){
32             StringBuilder sb = new StringBuilder();//其实递归过程中可以直接用sb的,但是感觉没有list方便,因此偷了一个懒
33             for(String str : list){
34                 sb.append(str).append(" ");
35             }
36             res.add(sb.toString().trim());
37             return;
38         }
39         List<Integer> preList = preMap.get(index);
40         for(int pre:preList){
41             String str = s.substring(pre,index);
42             list.add(0,str);
43             getList(list,pre,s,preMap);
44             list.remove(0);
45         }
46     }
47 }

 

posted on 2014-08-24 22:49  喵星人与汪星人  阅读(283)  评论(0编辑  收藏  举报