您的位置:首页 > 编程语言 > Java开发

leetcode 140:Word Break II 采用很巧妙的动态规划和DFS联合使用 JAVA源代码实现

2015-12-22 19:20 597 查看
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.思路1

第一个想法就是跟word break一样,直接DFS暴力检索,不出所料,TML了

2.思路2

暴力检索肯定不行,那么就优化。想到能否使用动态规划,首先搜索一下那些字符串是包含在dict中,形成一个动态规划的数组,去掉一些无用的搜索,然而依旧TML

3.思路3

1.既然想到动态规划剪枝了,再多想以下,我们不只是需要考虑当前子串在字典中,还要考虑当前子串之前的字符串也在字典中,这样将大大减少搜索路径。
2.我们查找是否包含在字典中是从前往后找的,那么我们找相关路径的时候反向遍历将会大大减少搜索路径。
实现了以上两点就已经大大优化了我们的检索。
具体实现代码如下:
List<String> result;
public List<String> wordBreak(String s, Set<String> wordDict) {
result = new ArrayList<String>();
int n = s.length();
//对每一个i都形成一个可以跳跃的点
List<Integer>[] pointer = new List
;
for(int i=0;i<n;i++) pointer[i]=new ArrayList<Integer>();
//动态规划形成跳跃点
for(int i=0;i<n;i++){
for(int j=0;j<=i;j++){
//递归的保证j-1可以形成单词,大大地剪枝
if(wordDict.contains(s.substring(j,i+1))&&(j==0||pointer[j-1].size()>0))
pointer[i].add(j);
}
}
//从后往前的递归
helper(pointer, s, n-1, "");
return result;
}
//DFS
public void helper(List<Integer>[] pointer, String s, int i, String pattern){
if(i<0){
result.add(pattern);
return;
}
for(Integer item:pointer[i]){
String nextPattern = pattern.length()==0?s.substring(item,i+1):s.substring(item,i+1)+" "+pattern;
helper(pointer, s, item-1, nextPattern);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息