算法修炼Day46|139.单词拆分·多重背包

80 阅读1分钟

LeetCode:139. 单词拆分 - 力扣(LeetCode)

1.思路

理解题意:将字符串s可以看作为背包,而wordDict是物品,判断字典物品重复加入背包是否能组成s。将字符串s进行一个个位置的截取,先遍历背包再遍历物品,因为物品可以重复加入。

难点:dp[]定义初始化:dp[0]= true(表示空字符串),dp[i] = true的前提条件是:dp[j] = true && dp[i - j] = true;

2.代码实现
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        // 动规
        HashSet<String> set = new HashSet<>(wordDict); // 存放子字典
        // 定义:dp[i]—表示i这么长通过字典可以组合起来,是true。最坏情况是一个字符重复组合
        boolean[] dp = new boolean[s.length() + 1];
        dp[0] = true;
        // 遍历 + 推导
        for (int i = 1; i <= s.length(); i++) { // 先背包
            for (int j = 0; j < i && !dp[i]; j++) { // 后物品(物品可以重复)
                if (set.contains(s.substring(j, i)) && dp[j]) {
                    dp[i] = true;
                }
            }
        }
        return dp[s.length()];
    }
}
3.复杂度分析

时间复杂度:O(n^2).

空间复杂度:O(n).

背包小结:

整体产生个逻辑框架,一个背包,n个不同大小的物品weight[i]具有不同的value[i],装入背包所产生的最大价值maxValue[]。 一个背包,多个物品,最少多少个物品能把背包装满。

物品和背包遍历的顺序,当物品可以重复时,先背包再物品。物品不能重复时,先物品再背包。