1 声明
1.1 首先,大家常常把这道题当作了背包问题来做,因为其循环结构和背包问题刚好相反,但事实如此嘛?
背包问题通常都是组合问题,这其实是一道“”面向目标值的排列问题“,具体和背包问题有什么不同可以参考我下面写的这篇文章“面向目标值的排列匹配“和“面向目标值的背包组合问题“的区别和leetcode例题详解
2 原题
public boolean wordBreak(String s, List<String> wordDict) {
int n=s.length();
char[]cs=s.toCharArray();
int m=wordDict.size();
HashSet<String>set=new HashSet<>(wordDict);
boolean[]f=new boolean[n+1];
f[0]=true;
for(int i=1;i<=n;i++){
for(int j=0;j<i;j++){
if(f[j]&&set.contains(s.substring(j,i))){
f[i]=true;
break;
}
}
}
return f[n];
}
3 改编一:求凑成目标串的方案数,如果凑不成返回0
//求方案数,使用两个函数
public int wordBreak3(String s, List<String> wordDict) {
int n=s.length();
char[]cs=s.toCharArray();
int m=wordDict.size();
HashSet<String>set=new HashSet<>(wordDict);
boolean[]f=new boolean[n+1];
f[0]=true;
int[]f2=new int[n+1];
f2[0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<i;j++){
if(f[j]&&set.contains(s.substring(j,i))){
f[i]=true;
f2[i]+=f2[j];
}
}
}
return f2[n];
}
// 方案二:直接使用一个dp函数
public int wordBreak(String s, List<String> wordDict) {
int n=s.length();
char[]cs=s.toCharArray();
int m=wordDict.size();
HashSet<String>set=new HashSet<>(wordDict);
int[]f2=new int[n+1];
f2[0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<i;j++){
if(f2[j]>0&&set.contains(s.substring(j,i))){
f2[i]+=f2[j];
}
}
}
System.out.println(f2[n]);
return true;
}