单词拆分
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:
拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
示例 1:
输入: s = “leetcode”, wordDict = [“leet”, “code”]
输出: true
解释: 返回 true 因为 “leetcode” 可以被拆分成 “leet code”。
示例 2:
输入: s = “applepenapple”, wordDict = [“apple”, “pen”]
输出: true
解释: 返回 true 因为 “applepenapple” 可以被拆分成 “apple pen apple”。
注意你可以重复使用字典中的单词。
示例 3:
输入: s = “catsandog”, wordDict = [“cats”, “dog”, “sand”, “and”, “cat”]
输出: false
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int []flag=new int[s.length()];
int j;
for(int i=0;i<s.length();i++){//计算每一位的状态
flag[i]=judge(s,0,i,wordDict);//首先看一下能不能找到直接匹配的
if(flag[i]==0){//如果不能
j=i-1;//那么j=i-1,j往前面走
while(j>=0){
if(flag[j]==1){//如果某一位的状态是可以到达的
flag[i]=judge(s,j+1,i,wordDict);//那么判断一下从这一位的下一位开始,到i结束,这一部分可不可以找到匹配的
if(flag[i]==1)break;//如果可以,那么break循环,接着去计算下一位的状态
}
j--;//如果没有break循环,那么必然没有找到匹配的,那么j再往前走。如果一直没找到,那么状态不会更改,还是0
}
}
}
return (flag[s.length()-1]==1);//最终看一下最后一位的状态是不是可以到达的,如果是,那么返回true
}
public int judge(String s,int start,int end,List<String>wordDict){//判断s从start开始,到end结束,能不能在字典中找到直接匹配的
String t=s.substring(start,end-start+1);
for(String word:wordDict){//判断哪个单词能够直接匹配
if(t==word)
return 1;
}
return 0;
}
}
解法:动态规划
首先从字符串的最开始,到当前位,看一下有没有直接匹配的。
如果有,那么进行下一位的状态判断。
如果没有,那么往前看,前面哪一位状态是可以到达的,从这一位的下一位开始,到当前位结束,这一部分看可不可以在字典中直接匹配到。
如果还是不行,那么再往前找哪一位状态是可以到达的,同样从这一位的下一位开始,到当前位结束,这一部分可不可以在字典中直接匹配到。
……
最终没有找到的话,那么把这一位的状态定义为不可到达的,再进行下一位的状态判断。
特点:
1、强调每一位的状态。
2、每一位的状态计算往往跟前几位有关系,也就是存在对前面状态的依赖性。