当然,还有另一种动态规划的思路,dp[i]表示 [0 ~ i]中分割的全部子串能否都在字符串集合中。 区别在于 i 是开头还是结尾罢了。
经验教训
从dfs 到动态规划
涉及到字符串集合时,想到利用 Tire Tree
代码实现
dfs(TLE)
public boolean wordBreak(String s, List<String> wordDict) {
HashSet<String> set = new HashSet<>();
set.addAll(wordDict);
char[] chs = s.toCharArray();
return dfs(chs, 0, set);
}
public boolean dfs(char[] chs, int i, HashSet<String> set) {
if (i == chs.length) {
return true;
}
for (intend = i; end < chs.length; ++end) {
String s = newString(chs, i, end - i + 1);
if (set.contains(s) && dfs(chs, end + 1, set)) {
return ture;
}
}
return false;
}
动态规划
public boolean wordBreak(String s, List<String> wordDict) {
HashSet<String> set = new HashSet<>();
set.addAll(wordDict);
char[] chs = s.toCharArray();
//dp[i] : i ~ chs.length - 1 可以由set中字符串构成
boolean[] dp = new boolean[chs.length + 1];
dp[chs.length] = true;
for (int i = chs.length - 1; i >= 0; --i) {
for (int end = i; end < chs.length; ++end) {
String newStr = new String(chs, i, end - i + 1);
if (set.contains(newStr) && dp[end + 1]) {
dp[i] = true;
break;
}
}
}
return dp[0];
}
动态规划(统计最大长度)
publicboolean wordBreak(String s, List<String> wordDict) {
HashSet<String> set = new HashSet<>();
int maxLength = 0;
//统计字符串集合里面字符串的最大长度for (String str : wordDict) {
maxLength = Math.max(maxLength, str.length());
set.add(str);
}
char[] chs = s.toCharArray();
//dp[i] : i ~ chs.length - 1 可以由set中字符串构成boolean[] dp = newboolean[chs.length + 1];
dp[chs.length] = true;
for (int i = chs.length - 1; i >= 0; --i) {
for (int end = i; end < chs.length && end - i + 1 <= maxLength; ++end) { //不超过maxLength
String newStr = new String(chs, i, end - i + 1);
if (set.contains(newStr) && dp[end + 1]) {
dp[i] = true;
break;
}
}
}
return dp[0];
}