3.单词拆分

 

 

要解决这个问题,可以使用动态规划的思路。具体来说,我们定义一个布尔数组 `dp`,其中 `dpi` 表示字符串 `s` 的前 `i` 个字符是否可以通过字典中的单词拼接而成。以下是详细的实现思路和代码:

 

---

 

 解题思路

1. 动态规划定义  

   用 `dpi` 表示 `s` 的前 `i` 个字符(即 `s0..i-1`)能否被字典中的单词拼接。初始时,`dp0 = true`(空字符串默认合法)。

 

2. 状态转移  

   对于每个位置 `i`,遍历所有可能的分割点 `j`(`0 ≤ j < i`)。若 `dpj` 为 `true`(即前 `j` 个字符已合法),且子串 `sj..i-1` 存在于字典中,则 `dpi` 设为 `true`。

 

3. 优化查询效率  

   将字典转换为哈希集合 `unordered_set`,使单词查询的时间复杂度降为 `O(1)`。

 

4. 遍历顺序  

   外层遍历 `i` 从 `1` 到 `s.length()`,内层遍历 `j` 从 `0` 到 `i-1`。当找到合法的分割点时,可提前终止内层循环。

 

---

 

 代码实现

cpp

include <vector>

include <unordered_set>

include <string>

 

using namespace std;

 

class Solution {

public:

    bool wordBreak(string s, vector<string>& wordDict) {

        unordered_set<string> dict(wordDict.begin(), wordDict.end());

        int n = s.size();

        vector<bool> dp(n + 1, false);

        dp0 = true; // 空字符串初始为true

 

        for (int i = 1; i <= n; ++i) {

            for (int j = 0; j < i; ++j) {

                if (dpj && dict.count(s.substr(j, i - j))) {

                    dpi = true;

                    break; // 找到一个合法分割即可终止内层循环

                }

            }

        }

        return dpn;

    }

};

 

---

 

 关键点分析

1. 动态规划数组初始化  

   空字符串的合法性是递推的基础,因此 `dp0` 必须初始化为 `true`。

 

2. 子串查询优化  

   使用 `unordered_set` 存储字典,查询时间复杂度为 `O(1)`,显著提升效率。

 

3. 提前终止内层循环  

   一旦找到合法的分割点 `j`,即可标记 `dpi` 为 `true` 并跳出内层循环,减少不必要的计算。

 

---

 

 复杂度分析

- 时间复杂度:`O(n^2)`,其中 `n` 是字符串 `s` 的长度。两层循环最坏情况下需要遍历所有可能的分割点。

- 空间复杂度:`O(n + m)`,`n` 是 `dp` 数组的大小,`m` 是字典中单词的数量(哈希集合的空间开销)。

 

---

 

 示例验证

以输入 `s = "leetcode", wordDict = "leet", "code"` 为例:

1. `i=4` 时,`j=0`,子串 `"leet"` 在字典中,`dp4` 设为 `true`。

2. `i=8` 时,`j=4`,子串 `"code"` 在字典中,`dp8` 设为 `true`,最终返回 `true`。

 

此方法通过动态规划高效地解决了字符串拼接问题,适用于字典单词可重复使用的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Despacito0o

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值