题目:
给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
方法一:回溯法
回溯法其实很简单 就是每次选择一个单词去排列组合 (因为这里是可以重复选的 所以你回溯的起始位置不用往后加 也就是说每次选择你都要从头开始去选)这个方法的改进就是在做选择的时候或者是判断是否结束回溯的时候 去**匹配已选的字符串是否是目标串的前缀 **因为目前的结果如果都不是前缀 往后再继续选也不会是正确答案
这个方法是无法过力扣的测试用例的 因为时间复杂度太高了
class Solution {
String singleResult;
boolean result;
public void chooseString(int begin,String s,List<String> wordDict){
System.out.println("-------------------------------");
if(result||singleResult.length()>s.length()){
return;
}
if(singleResult.length()==s.length()&&singleResult.equals(s)){
result=true;
return;
}
System.out.println("singleResult:"+singleResult);
if(singleResult.length()>0&&singleResult.length()<=s.length()){
String head=s.substring(0,singleResult.length());
System.out.println("head:"+head);
if(!singleResult.equals(head)){
return;
}
}
for(int i=begin;i<wordDict.size();i++){
String temp=singleResult;
singleResult=singleResult+wordDict.get(i);
chooseString(begin,s,wordDict);
singleResult=temp;
}
}
public boolean wordBreak(String s, List<String> wordDict) {
singleResult="";
result=false;
chooseString(0,s,wordDict);
return result;
}
}
方法二:动态规划
题目是单词拆分 我们转换思路 其实就是去选wordDict里面的单词组成目标字符串
解题思路如图下所示:
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
boolean[] dp=new boolean[s.length()+1];
Arrays.fill(dp,false);
// 如果dp[0]是false那么后面推理的都是false
dp[0]=true;
for(int i=1;i<=s.length();i++){
System.out.println("--------");
for(int j=0;j<i;j++){
if(dp[i]==true){
break;
}
String sub=s.substring(j,i);
System.out.println("sub:"+sub);
if(wordDict.contains(sub)){
dp[i]=dp[j];
}else{
dp[i]=false;
}
}
}
return dp[s.length()];
}
}