代码随想录刷题day46| 单词拆分&&多重背包一刷跳过


day46学习内容

day46主要内容

  • 单词拆分
  • 多重背包理论基础

声明
本文思路和文字,引用自《代码随想录》


一、单词拆分

139.原题链接

1.1、动态规划五部曲

1.1.1、 确定dp数组(dp table)以及下标的含义

表示字符串 s 的前 i 个字符(具体而言,是从字符串的开始到位置 i-1,因为字符串索引是从0开始的)能否被分割成一个或多个在字典 wordDict 中出现的单词。

换句话说,如果 dp[i] 为 true,则意味着存在至少一种方式将 s 的前 i 个字符分割成若干个单词,这些单词全部包含在给定的单词列表 wordDict 中。这里的 i 取值范围是从 0 到 s.length(),其中 dp[0] 特别表示空字符串,按照定义,空字符串可以被视为可以被分割(即没有需要分割的内容),因此 dp[0] 初始化为 true。

1.1.2、确定递推公式

想不到,抄的题解。。

1.1.3、 dp数组如何初始化

dp[0] = true;

1.1.4、确定遍历顺序

先遍历物品后遍历背包。

1.2、代码

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        HashSet<String> set = new HashSet<>(wordDict);
        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()];
    }
}

1.2.1、如何理解这段代码

初始化

  • 定义一个布尔型数组 dp,其长度为 s.length() + 1dp[i] 表示字符串 s 的前 i 个字符(即 s.substring(0, i))能否被拆分为一个或多个在字典中出现的单词。
  • dp[0] = true 表示空字符串默认是可以被拆分的,这是动态规划的基础情况。

动态规划过程

  • 外层循环:遍历字符串 s 的每一个字符,索引为 i,从 1 开始到 s.length()(包括)。i 代表当前考虑的字符串长度。
  • 内层循环:对于每个 i,再次从头遍历到 i,索引为 j,用于尝试找到所有可能的拆分点。j 表示尝试将字符串拆分为两部分:s[0...j]s[j+1...i]
    • 检查条件:
      1. dp[j] 是否为 true,即 s[0...j] 部分是否可以被成功拆分。
      2. s.substring(j, i) 是否存在于 set 中,即 s[j+1...i] 部分是否为字典中的一个单词。
    • 如果这两个条件同时满足,说明找到了一种方式将 s[0...i] 成功拆分,将 dp[i] 设置为 true

返回结果

  • 最后返回 dp[s.length()] 的值。如果为 true,则表示整个字符串 s 可以被拆分为一个或多个在字典中出现的单词;否则,不可以。

举个例子
假设 s = "leetcode"wordDict = ["leet", "code"]

  • 初始化 dp = [true, false, false, false, false, false, false, false, false]
  • i = 4j = 0 时,dp[0]trues.substring(0, 4)(即 “leet”)在 set 中,因此 dp[4] 被设置为 true
  • 同理,当 i = 8j = 4 时,dp[4]trues.substring(4, 8)(即 “code”)在 set 中,因此 dp[8] 也被设置为 true
  • 最终 dp[8]true,表示整个字符串可以被拆分。

二、完全背包理论基础

一刷先放过自己。

总结

1.感想

  • 单词拆分这一题,状态转移方程想不出来一点。。根本想不到

2.思维导图

本文思路引用自代码随想录,感谢代码随想录作者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值