139. 单词拆分
单词就是物品,字符串s就是背包,单词能否组成字符串s,就是问物品能不能把背包装满。
拆分时可以重复使用字典中的单词,说明就是一个完全背包!
如果求组合数就是外层for循环遍历物品,内层for遍历背包。
如果求排列数就是外层for遍历背包,内层for循环遍历物品。
这里其实是求排列 所以需要外层for遍历背包,内层for循环遍历物品
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int n = s.length();
boolean[] dp = new boolean[n + 1];
dp[0] = true;
for(int i = 0; i <= n; i++){
for(int j = 0; j < wordDict.size(); j++){
if(wordDict.get(j).length() <= i && compare(wordDict.get(j), s, i - wordDict.get(j).length())){
dp[i] = dp[i] ? true : dp[i - wordDict.get(j).length()];
}
}
}
return dp[n];
}
private boolean compare(String str, String s, int start){
char[] strChar = str.toCharArray();
char[] sChar = s.toCharArray();
for(int i = 0; i < strChar.length; i++){
if(strChar[i] != sChar[start++]){
return false;
}
}
return true;
}
}
不够简洁
因为有重复 所以先放入Set集合去重
HashSet<String> set = new HashSet<>(wordDict);
可以通过set.contains() 来判断set集合中是否有出现指定的字符串
set.contains(s.substring(j, i))
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
HashSet<String> set = new HashSet<>(wordDict);
boolean[] valid = new boolean[s.length() + 1];
valid[0] = true;
for (int i = 1; i <= s.length(); i++) {
for (int j = 0; j < i && !valid[i]; j++) {
if (set.contains(s.substring(j, i)) && valid[j]) {
valid[i] = true;
}
}
}
return valid[s.length()];
}
}