力扣HOT100(51) 动态规划-单词拆分

动态规划核心思路(一句话讲透)

dp[i]表示:字符串s的前i个字符(也就是s[0..i-1]),能不能被字典里的单词拼接出来

对于每个位置i,我们只需要找一个分割点j0 ≤ j < i),满足两个条件:

  1. j个字符已经可以被拆分:dp[j] == true
  2. ji的子串s[j..i-1],正好在字典里

只要存在这样一个j,那么dp[i]就等于true

完整解题步骤 --哈希表 dp 遍历双循环一个i负责变量s 一个j负责遍历0-i的分割点 看所有分割的可能

1. 预处理字典:转成哈希集合

为了快速判断一个子串是否在字典里,我们先把wordDict转成unordered_set,这样查找的时间复杂度是 O (1),比直接遍历数组快很多。

2. 初始化 dp 数组

  • 数组长度:s.size() + 1(因为要表示前 0 个到前 n 个字符,共 n+1 种状态)
  • 所有元素初始化为false
  • 边界条件dp[0] = true
    • 前 0 个字符就是空串,空串不需要任何单词就能拼接出来,所以是合法的
    • 这是所有推导的基础,没有这个条件,整个 dp 数组都会是 false

3. 遍历计算 dp 数组

  • 外层循环:i1s.size(),表示当前要判断前i个字符能不能被拆分
  • 内层循环:j0i-1,枚举所有可能的分割点
    • 如果dp[j] == true(前 j 个字符合法),并且子串s.substr(j, i-j)在字典里
    • 那么dp[i] = true,直接 break 内层循环(只要找到一个合法的分割点就行)

4. 返回结果

dp[s.size()]就是整个字符串能不能被拆分的答案。

cpp 复制代码
class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        //转为哈希表集合
        unordered_set<string> wordSet;
        for(string word : wordDict){
            wordSet.insert(word);
        }

        //初始化dp数组
        //dp[i]表示前i个字符能不能被拆分
        int n  = s.size();
        vector<bool> dp(n+1,false);//n+1个数 初始值都是false
        dp[0] = true;//边界条件

        //遍历
        for(int i = 1;i<=n;i++){
            //分割点
            for(int j = 0;j<i;j++){
                if(dp[j] && wordSet.count(s.substr(j,i-j))){
                    dp[i] = true;
                    break;
                }
            }
        }

        return dp[n];
    }
};
相关推荐
青山木21 分钟前
Hot 100 --- 最长递增子序列
java·数据结构·算法·leetcode·动态规划
土司大王1 小时前
LeetCode hot100——33.搜索旋转排序数组:Java 二分模板与 O(log n) 实现
数据结构·算法·leetcode
不穿鞋的懒羊羊1 小时前
STL容器
算法
huang5791471 小时前
多线程环境下的共享数据结构安全问题分析4
算法
地平线开发者1 小时前
模型部署|征程6 量化路线怎么选:PTQ 还是 QAT?
神经网络·算法·机器学习
辰辉创聚2 小时前
禽流感病毒分子基础:表面抗原与内部转录复合体的功能解析
ide·leetcode·rabbitmq·重组血凝素蛋白·甲型流感病毒核蛋白·禽流感单抗
不会就选b2 小时前
算法日常・每日刷题--<贪心>12
算法
小羊没烦恼!2 小时前
Memory 记忆设计讨论:为什么 Agent Memory 不能只靠向量数据库?
java·开发语言·windows·算法·c#
ysu_03143 小时前
08-二叉树遍历:四种方式详解
c语言·数据结构·算法·leetcode
咸鱼老弟3 小时前
Speculative Decoding(投机采样):大模型"先猜后验",生成速度翻倍
前端·算法·ai编程