leetcode-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”]. 
思路分析:这题可以用DFS 搜索递归做,基本是brute force的解法,dfs函数要维护的量包括startIndex,preWords和res,startIndex表示当前进行word break的起点,也就是说前面如果已经被break了,应该排除在外。preWords主要维护目前已经breaked的string前面的部分,后面从startIndex一旦发现新的word可以添加到preWords之后,dfs返回的条件是当startIndex已经越界,也就是>=s.length()了,就把当前得到的word break方案加入res。从题目的实例我们也可以看出,同一个字符串可以有多个word break方案,因此我们从前向后scan 字符串发现第一个可以break的词的时候需要更新preWords进行dfs递归调用。这题是NP问题,时间复杂度为O(2^n)也就是指数级别。 这类DFS递归搜索的题目有很多,除了word break,还有八皇后,Sudoku Solver等等,都是这类题目,在面试中很常见,要多加练习。 
AC Code:以下是brute force DFS搜索AC的从code。由于LeetCode有一个很长的不能break的测试用例,因此把word break I 判断能否break的函数作为sub routine,先判断一下能否break,如果不能直接返回空容器。

复制代码
 1 public class Solution {  
 2     public List<String> wordBreak(String s, Set<String> dict) {  
 3         ArrayList<String> res = new ArrayList<String>();  
 4         if(s == null || s.isEmpty() || !wordBreakCanDo(s, dict)){  
 5             return res;  
 6         }  
 7         dfs(s, dict, 0, "", res);  
 8         return res;  
 9     }  
10       
11     //10:08  
12     public void dfs(String s, Set<String> dict, int startIndex, String preWords, ArrayList<String> res){  
13         if(startIndex >= s.length()){  
14             //return contition is that the startIndex has been out of bound  
15             res.add(preWords);  
16             return;  
17         }  
18         for(int i = startIndex; i < s.length(); i++){  
19             String curStr = s.substring(startIndex, i+1);  
20             if(dict.contains(curStr)){  
21                 String newSol;  
22                 if(preWords.length() > 0){  
23                     newSol = preWords + " " + curStr;  
24                 } else {  
25                     newSol = curStr;  
26                 }  
27                 dfs(s, dict, i + 1, newSol, res);  
28             }  
29         }  
30     }  
31     //1021  
32       
33     public boolean wordBreakCanDo(String s, Set<String> dict) {  
34         s = "#" + s;  
35         boolean[] canSegmented = new boolean[s.length()];  
36           
37         canSegmented[0] = true;  
38         for(int i = 1; i < s.length(); i++){  
39             for(int k = 0; k < i; k++){  
40                 canSegmented[i] = canSegmented[k] && dict.contains(s.substring(k + 1, i + 1));  
41                 if(canSegmented[i]) break;  
42             }  
43         }  
44         return canSegmented[s.length() - 1];  
45     }  
46 }  
复制代码

转自:http://blog.csdn.net/yangliuy/article/details/43602313

posted @   鸭子船长  阅读(276)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2016-01-12 ubuntu14.04无法连接有线连接问题
2016-01-12 ANDROID颜色设置
2016-01-12 android 从Activity 获取 rootView 根节点
2016-01-12 获取当前View
2016-01-12 Cannot make a static reference to the non-static method的解决方法
2016-01-12 Android 不同View ID相同
2016-01-12 WindowManager.LayoutParams全解
点击右上角即可分享
微信分享提示