Word Break I
参考代码
http://needjobasap.blogspot.com/2014/11/word-break-leetcode.html
http://fisherlei.blogspot.com/2013/11/leetcode-word-break-solution.html
"
possible[i] = true if S[0,i]在dictionary里面
= true if possible[k] == true 并且 S[k+1,j]在dictionary里面, 0<k<i
= false if no such k exist.
"
public class Solution {
// http://needjobasap.blogspot.com/2014/11/word-break-leetcode.html
//http://fisherlei.blogspot.com/2013/11/leetcode-word-break-solution.html
public boolean wordBreak(String s, Set<String> dict) {
boolean[] dp = new boolean[s.length()+1];
dp[0] = true;
// for(int i=0;i<s.length();i++){ 注意这里
for(int i=1;i<=s.length();i++){
for(int j=0; j< i; j++){
if(dp[j] && dict.contains(s.substring(j,i))) {
dp[i]=true;
break;
}
}
}
return dp[s.length()];
}
}
Word Break II
http://www.danielbit.com/blog/puzzle/leetcode/leetcode-word-break-ii
总结的比较好的算法
public class Solution {
// https://stupidcodergoodluck.wordpress.com/2013/11/16/leetcode-word-break-ii/
public ArrayList<String> wordBreak(String s, Set<String> dict) {
ArrayList<String> ret = new ArrayList<String>();
if (s==null || s.length()==0) return ret;
int n = s.length();
boolean[] dp = new boolean[n+1];
dp[0] = true;
for(int i=1;i<=s.length();i++){
for(int j=0; j< i; j++){
if(dp[j] && dict.contains(s.substring(j,i))) {
dp[i]=true;
break; // dp[i] = true了,则j to i 的dp就不用再接着判断了
}
}
}
if (dp[n] == false) return ret; //DP的作用就这一行!!!
StringBuilder cur = new StringBuilder();
dfs(s, 0, cur, ret, dict);
return ret;
}
public void dfs(String s, int start, StringBuilder cur, ArrayList<String> ret, Set<String> dict) {
int n = s.length();
if (start >= n) {
ret.add(new String(cur)); //该时空完成 收集结果
return;
}
for (int i=start+1; i<=n; i++) { // start+1 为啥,因为下一行从start到i
String sub = s.substring(start, i); //每个时空之内起点都是一样的,start
if (dict.contains(sub)) {
int oldLen = cur.length();
if (oldLen!=0) cur.append(" ");
cur.append(sub);
dfs(s, i, cur, ret, dict); //平行时空发射,各自带着不一样的start = i
cur.delete(oldLen, cur.length()); // 本时空内改变历史复原,只是在dfs 中才update了传入的cur
}
}
}
}