139.单词拆分
Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words.
Input: s = “applepenapple”, wordDict = [“apple”,“pen”]
Output: true
Explanation: Return true because “applepenapple” can be segmented as “apple pen apple”.
Note that you are allowed to reuse a dictionary word.
单词就是物品,字符串s就是背包,单词能否组成字符串s,就是问物品能不能把背包装满。
注意这里,遍历顺序是重要的,每个排列都不相同
dp[i] : 字符串长度为i的话,dp[i]表示到字符串长度i时有多少个连续word组成。
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
int[] dp = new int[s.length()+1];
for (int i = 0; i < wordDict.size(); i++) {
if (wordDict.get(i).length() <= s.length() && s.subSequence(0, wordDict.get(i).length()).equals(wordDict.get(i))){
dp[wordDict.get(i).length()] = 1;
}
}
for (int j = 0; j <= s.length(); j++) {
for (int i = 0; i < wordDict.size(); i++) {
if (j > wordDict.get(i).length() && dp[j-wordDict.get(i).length()] != 0 && s.subSequence(j-wordDict.get(i).length(), j).equals(wordDict.get(i))){
dp[j] = dp[j-wordDict.get(i).length()] + 1;
}
}
}
if (dp[dp.length-1] == 0) return false;
return true;
}
}
dp[i] : 字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词。
这里的物品是wordDict中的word,dp[j]想要得到,首先基于此前的dp,看遍历的物品word是不是结尾的子字符串,是就true
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
boolean[] dp = new boolean[s.length()+1];
dp[0] = true;
for (int i = 1; i < dp.length; i++) {
dp[i] = false;
}
for (int i = 1; i <= s.length(); i++) { // 遍历背包s
for (int j = 0; j < wordDict.size(); j++) { // 遍历物品每个word,看最后相同长度的子字符串是不是wordDict中的word
if (i-wordDict.get(j).length() >= 0 && s.subSequence(i-wordDict.get(j).length(),i).equals(wordDict.get(j)) && dp[i-wordDict.get(j).length()]==true) {
dp[i] = true;
}
}
}
return dp[s.length()];
}
}
如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里,那么dp[i]一定是true。(j < i )。
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
boolean[] dp = new boolean[s.length()+1];
dp[0] = true;
for (int i = 1; i < dp.length; i++) {
dp[i] = false;
}
for (int i = 1; i <= s.length(); i++) { // 遍历背包s字符串
for (int j = 0; j < i; j++) { // 遍历物品(j-i的子字符串)
String substr = s.substring(j, i);
if (wordDict.contains(substr) && dp[j]==true) {
dp[i] = true;
}
}
}
return dp[s.length()];
}
}
● 关于多重背包,你该了解这些!
● 背包问题总结篇!