思路:
1 思考子问题:dfs(i)表示,从i到结尾的字串能否拆分
2 递推公式:dfs(i) = s.substring(i, t) && dfs(t)
3 记忆化搜索
4 转为动态规划 f[i] = s.substring(i, t) && f[t]
4.1 t要从i + 1一直遍历到结尾,为了利用到之前算到的结果,所以i从后向前遍历,j从i+1遍历到结尾。
4.2 初始化值f[n] = true 最终结果为f[0]
总结:
子问题-->递推公式-->记忆化搜索-->动态规划
动态规划:递推公式-->遍历顺序-->返回值
代码:
class Solution {
public boolean wordBreak(String s, List<String> wordDict) {
Set<String> set = new HashSet<>();
for(String str : wordDict) {
set.add(str);
}
int n = s.length();
// dp[i],以i打头的字串是否能拆分
boolean[] dp = new boolean[n + 1];
// 空串可以拆分 初始化
dp[n] = true;
for(int i = n - 1; i >= 0; i--) {
for(int j = i + 1; j <= n; j++) {
// i ~ n 的字串可以分为 i ~ j 和 j ~ n
if(set.contains(s.substring(i, j)) && dp[j]) {
dp[i] = true;
}
}
}
// 返回值
return dp[0];
}
}
参考: