https://leetcode-cn.com/problems/word-break/
给定一个非空字符串 s 和一个包含非空单词列表的字典 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。
说明:
拆分时可以重复使用字典中的单词。
你可以假设字典中没有重复的单词。
package factory;
import java.util.ArrayList;
import java.util.List;
/**
* @Description: 单词拆分(动态规划法)
* https://leetcode-cn.com/explore/interview/card/top-interview-quesitons-in-2018/275/string/1138/
* @Author: Jaryn
* @Date: 2019/12/6 14:05
*/
public class WordBreak2 {
public static void main(String[] args) {
String s = "catsandog";
ArrayList<String> strings = new ArrayList<>();
strings.add("cats");
strings.add("dog");
strings.add("sand");
strings.add("and");
strings.add("cat");
System.out.println(wordBreak(s, strings));
}
/**
* 使用动态规划,比如单词cars,[true, c是否组合存在,ca是否组合存在,car是否组合存在,cars是否组合存在]
* 所以ca是否存在的前提是 (c存在&&a存在) || (ca是否存在)
* car是否存在的前提是 (c存在&&ar存在)|| (ca存在&&r存在) || (car存在)
* @param s
* @param wordDict
* @return
*/
public static boolean wordBreak(String s, List<String> wordDict) {
int len = s.length();
boolean[] bs = new boolean[len + 1];
bs[0] = true;
for(int i=1; i<=len; i++) { // 代表数组的长度
for(int j=0; j<i; j++) { // 代表从上一步的基础上,验证组合的可能
if(bs[j]) { // 上一步的组合是否存在,比如到car的时候,c存在走下一步,ca存在走下一步
String sub = s.substring(j, i); // 截取后面的字符串,比如到car,上一步c存在,那么截取ar。
if(wordDict.contains(sub)) { // 判断ar是否存在
bs[i] = true; // 存在的话证明car这个组合是存在的
break; // 存在直接break,因为已经找到了
}
}
}
}
return bs[len]; // 最后面的boolean证明了整个组合是否存在的
}
}