我正在尝试理解以下Java +动态编程实现(https://pingzhblog.wordpress.com/2015/09/17/word-break/):
public class Solution {
public boolean wordBreak(String s, Set<String> wordDict) {
if(s == null) {
return false;
}
boolean[] wordBreakDp = new boolean[s.length() + 1];
wordBreakDp[0] = true;
for(int i = 1; i <= s.length(); i++) {
for(int j = 0; j < i; j++) {
String word = s.substring(j, i);
if(wordBreakDp[j] && wordDict.contains(word)) {
wordBreakDp[i] = true;
break;
}
}
}//end for i
return wordBreakDp[s.length()];
}
}
但需要对String s = "abcxyz"
和Set <String> wordDict = ["z", "xy", "ab", "c"]
进行一些澄清。
我仍然不清楚wordBreakDp[]
代表什么,并将其设置为真意味着。
所以我做了尝试并获得wordBreakDP[2,3,5,6]=true
,但这些索引告诉了什么?我不能检查i=6
,因为我们正在检查的是wordBreakDp[]
的最后一个索引是否为真,wordBreakDp[s.length()];
?
比如我说ab
获得了s.substring(0, 2);
,但是我们怎么能假设下一个循环s.substring(1, 2);
没有用,只有break;
循环?
谢谢
答案 0 :(得分:0)
这不是一个真正的答案,但它可能有助于理解循环。它在每次迭代时打印substring(i,j)的值以及wordBreakDp [j]。它还在方法结束时打印最终解决方案(分段)。
public boolean wordBreak(String s, Set<String> wordDict) {
if(s == null) {
return false;
}
boolean[] wordBreakDp = new boolean[s.length() + 1];
wordBreakDp[0] = true;
for(int i = 1; i <= s.length(); i++) {
for(int j = 0; j < i; j++) {
String word = s.substring(j, i);
System.out.println("["+j+","+i+"]="+s.substring(j,i)+", wordBreakDP["+j+"]="+wordBreakDp[j]);
if(wordBreakDp[j] && wordDict.contains(word)) {
wordBreakDp[i] = true;
break;
}
}
}//end for i
for (int i = 1, start=0; i <= s.length(); i++) {
if (wordBreakDp[i]) {
System.out.println(s.substring(start,i));
start = i;
}
}
return wordBreakDp[s.length()];
}
答案 1 :(得分:0)
我想我能回答你的上一个问题:
并说例如我得到了s.substring(0,2);但是怎么可能 我们假设下一个循环,s.substring(1,2);,没用 只是休息走出循环?
你是对的,如果s.substring(0,2)得到“ab”并且你突破了循环,这并不一定意味着s.substring(1,2)没用。假设s.substring(1,2) 有用。这意味着“a”也是一个有效的单词,因此是“b”。该算法找到的解决方案将以“ab”开头,而未断开的解决方案将是“a”,后跟“b”。这两种解决方案都是正确的(假设字符串的其余部分也可以分解为有效字)。该算法未找到所有有效解决方案。如果字符串可以被分解为有效字,即,如果有一个解决方案满足条件,则它返回true。当然,可能有多个解决方案,但这不是此算法的目的。
答案 2 :(得分:0)
注意,f[i]
表示i
的第一个s
字符是否有效。示例,
String =
catsand
Dict =
[cat, cats, sand, and]
s = c a t s a n d
dp = T F F T T F F ?
i = 0 1 2 3 4 5 6 7
*
注意
dp[0]
为True,因为空字符串有效。假设我们dp[0]
到dp[6]
。让我们计算
dp[7]
,表示catsand
是否有效。
要使catsand
有效,dict中必须有非空后缀,其余前缀有效。
"catsand" is a valid, if:
If "" is valid, and "catsand" is inDict, or
If "c" is valid, and "atsand" is inDict, or
If "ca" is valid, and "tsand" is inDict, or
If "cat" is valid, and "sand" is inDict, or
If "cats" is valid, and "and" is inDict, or
If "catsa" is valid, and "nd" is inDict, or
If "catsan" is valid, and "d" is inDict
转换为pesudo代码:
dp[7] is True, if:
j j i
If dp[0] && inDict( s[0..7) ) or
If dp[1] && inDict( s[1..7) ) or
If dp[2] && inDict( s[2..7) ) or
If dp[3] && inDict( s[3..7) ) or
If dp[4] && inDict( s[4..7) ) or
If dp[5] && inDict( s[5..7) ) or
If dp[6] && inDict( s[6..7) )
答案 3 :(得分:0)
public class Solution {
public int wordBreak(String a, ArrayList<String> b) {
int n = a.length();
boolean dp[] = new boolean[n+1];
dp[0] = true;
for(int i = 0;i<n;i++){
if(!dp[i])continue;
for(String s : b){
int len = s.length();
int end = len + i;
if(end > n || dp[end])continue;
if(a.substring(i,end).equals(s)){
dp[end] = true;
}
}
}
if(dp[n])return 1;
else return 0;
}
}