【LeetCode 热题100】139:单词拆分(动态规划全解析+细节陷阱)(Go语言版)

news2025/4/18 20:17:15

🚀 LeetCode 热题 139:单词拆分(Word Break)| 动态规划全解析+细节陷阱

📌 题目描述

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请判断 s 是否可以由字典中出现的单词拼接成。

说明:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

🎯 示例 1:

输入:s = "leetcode", wordDict = ["leet", "code"]
输出:true
解释:返回 true 因为 "leetcode" 可以被拆分为 "leet code"。

🎯 示例 2:

输入:s = "applepenapple", wordDict = ["apple", "pen"]
输出:true
解释:可以拼接成 "apple pen apple",可以重复使用 wordDict 中的单词。

🎯 示例 3:

输入:s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出:false

💡 解题思路一:动态规划(DP)

我们定义一个布尔类型的一维数组 dp[i] 表示 s[0:i] 这个子串是否可以由字典中的单词组成。

🧱 状态定义:

我们用一个布尔数组 dp[i] 表示:

从字符串的起始位置(下标 0)到位置 i 的子串 s[0:i] 是否可以被成功拆分成一个或多个字典中的单词。

注意:这里的 i 是长度,不是下标(下标是 i-1)。


✅ 状态转移方程:

dp[i] = true,若存在 j,使得 dp[j] == true 且 s[j:i] 在 wordDict 中

也就是说,如果前面某个位置 j 之前的子串可以被拼出,并且 s[j:i] 在字典中,那 dp[i] 就可以设置为 true

✅ 初始条件:

dp[0] = true  // 空字符串可视为已完成

💻 Go 实现代码(动态规划)

func wordBreak(s string, wordDict []string) bool {
    wordSet := make(map[string]bool)
    for _, word := range wordDict {
        wordSet[word] = true
    }

    dp := make([]bool, len(s)+1)
    dp[0] = true

    for i := 1; i <= len(s); i++ {
        for j := 0; j < i; j++ {
            if dp[j] && wordSet[s[j:i]] {
                dp[i] = true
                break
            }
        }
    }
    return dp[len(s)]
}

🔍 注意点 & 边界问题解析

✅ 注意 1:不要和子串的下标混淆

  • dp[i] 代表的是前 i 个字符构成的子串(即 s[0:i]),而不是下标 i 的字符。
  • 所以判断子串是否在字典中时,要写 s[j:i],而不是 s[j:i+1]

✅ 注意 2:字典查找效率

使用 map[string]bool 构造一个哈希集合 wordSet 替代数组,可以让查找从 O(n) 降到 O(1),大幅提升效率:

wordSet := make(map[string]bool)
for _, word := range wordDict {
    wordSet[word] = true
}

✅ 注意 3:剪枝优化(提前结束)

只要在内层循环找到一个合法切割位置,就可以直接 break,节省无效循环。


✅ 注意 4:空字符串与空字典

  • s = "",返回 true,空字符串默认可以拆分(dp[0]=true)。
  • wordDict = [],返回 false,无单词可用无法拼出。

🌈 图解理解

假设输入:

s = "applepenapple"
wordDict = ["apple", "pen"]

我们依次维护 dp 状态:

i子串 s[0:i]能否拆分dp[i]
0“”true
5“apple”true
8“applepen”true
13“applepenapple”true

🧠 更深层的理解(背后的思想)

本题其实可以抽象为:

把一个字符串切成若干段,看这些段是否全都能在字典中找到。

也可以类比为:

一个人从字符串左端起跳,只能跳到在字典中出现的词结尾位置,问能否跳到终点。

所以动态规划是处理“前缀是否可达”这种问题的最优解。


⏳ 复杂度分析

类型复杂度
时间复杂度O(n²)
空间复杂度O(n)
  • n 是字符串长度。
  • 时间复杂度主要来自两层循环和切片操作。
  • 使用哈希集合加速查找操作。

🧠 解题思路二:记忆化搜索(DFS + 记忆化)

从起始位置出发,尝试所有可能的切割位置,只要有一个可行就返回 true

为了防止重复计算,使用 map[int]bool 进行记忆。


💻 Go 实现代码(记忆化 DFS)

func wordBreak(s string, wordDict []string) bool {
    wordSet := make(map[string]bool)
    for _, word := range wordDict {
        wordSet[word] = true
    }

    memo := make(map[int]bool)

    var dfs func(int) bool
    dfs = func(start int) bool {
        if start == len(s) {
            return true
        }
        if val, ok := memo[start]; ok {
            return val
        }

        for end := start + 1; end <= len(s); end++ {
            if wordSet[s[start:end]] && dfs(end) {
                memo[start] = true
                return true
            }
        }

        memo[start] = false
        return false
    }

    return dfs(0)
}

🔍 两种方法对比

方法优点缺点
动态规划性能稳定,逻辑清晰,适合面试高频实现上可能略显冗长
记忆化 DFS更贴近人类思考方式,递归直观有栈溢出风险,依赖剪枝优化

✅ 总结

  • 本题是经典的字符串 + 动态规划题型。
  • 动态规划和记忆化搜索都值得掌握!
  • 实际编码中推荐使用动态规划,执行效率更高。

🎁 加分思考

  • 如果要求输出所有可能的拆分方式?
  • 如果字典非常大,如何优化查找?(使用 Trie 前缀树)

🌟 更多高频算法题持续更新中…

欢迎点赞 👍、收藏 ⭐、评论 💬、关注 🧠,支持我继续输出优质 LeetCode 题解!💻📘📌


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2332334.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C语言】预处理(预编译)(C语言完结篇)

一、预定义符号 前面我们学习了C语言的编译和链接。 在C语言中设置了一些预定义符号&#xff0c;其可以直接使用&#xff0c;预定义符号也是在预处理期间处理的。 如下&#xff1a; 可以看到上面的预定义符号&#xff0c;其都有两个短下划线&#xff0c;要注意的是&#xff…

关于聊天室数据库建表

首先了解一下外键 ​​一、外键的本质​​ ​​定义​​&#xff1a;外键是某个表中的字段&#xff08;或字段组合&#xff09;&#xff0c;其值必须与另一张表的主键值相匹配。 ​​核心作用​​&#xff1a;强制数据一致性&#xff0c;维护表间关系。 二、外键的核心用途…

基于 OpenHarmony 5.0 的星闪轻量型设备应用开发-Ch1 开发环境搭建

写在前面&#xff1a; 文本所写的工程创建均是基于 HH-SPARK-WS63 星闪无线模组。 此篇是系列文章《基于 OpenHarmony5.0 的星闪轻量型设备应用开发》的第 1 章。 1.1 介绍 HH-SPARK-WS63 星闪无线模组&#xff08;以下简称 WS63&#xff09;是由润和软件推出的基于海思 WS63V…

离线安装 nvidia-docker2(nvidia-container-toolkit)

很多时候大家都有用docker使用gpu的需求&#xff0c;但是因为网络等原因不是那么好用&#xff0c;这里留了一个给ubuntu的安装包&#xff0c;网络好的话也提供了在线安装方式 安装 nvidia-docker2 1 离线安装 &#xff08;推荐&#xff09; unzip解压后进入目录 dpkg -i *.d…

第7篇:Linux程序访问控制FPGA端LEDR<五>

Q&#xff1a;如何设计.c程序代码实现FPGA端外设LEDR流水灯&#xff1f; A&#xff1a;在DE1-SoC开发板上实现的流水灯效果&#xff1a;一次只点亮一个红色LED&#xff0c;初始状态为向左移动直至点亮LEDR9&#xff0c;然后改变移动的方向为向右直至点亮LEDR0&#xff0c;以此…

Unity 实现伤害跳字

核心组件&#xff1a; Dotween TextMeshPro 过程轨迹如下图&#xff1a; 代码如下&#xff1a; using System.Collections; using System.Collections.Generic; using DG.Tweening; using TMPro; using UnityEngine; using UnityEngine.Pool;public class …

008二分答案+贪心判断——算法备赛

二分答案贪心判断 有些问题&#xff0c;从已知信息推出答案&#xff0c;细节太多&#xff0c;过程繁杂&#xff0c;不易解答。 从猜答案出发&#xff0c;贪心地判断该答案是否合法是个不错的思路&#xff0c;这要求所有可能的答案是单调的&#xff08;例&#xff1a;x满足条件…

衣橱管理助手系统(衣服推荐系统)(springboot+ssm+vue+mysql)含运行文档

衣橱管理助手系统(衣服推荐系统)(springbootssmvuemysql)含运行文档 该系统名为衣橱管理助手&#xff0c;是一个衣物搭配管理系统&#xff0c;主要功能包括衣物档案管理、衣物搭配推荐、搭配收藏以及套装智能推荐。用户可以通过系统进行衣物的搭配和收藏管理&#xff0c;系统提…

文件上传做题记录

1&#xff0c;[SWPUCTF 2021 新生赛]easyupload2.0 直接上传php 再试一下phtml 用蚁剑连发现连不上 那就只要命令执行了 2&#xff0c;[SWPUCTF 2021 新生赛]easyupload1.0 当然&#xff0c;直接上传一个php是不行的 phtml也不行&#xff0c;看下是不是前端验证&#xff0c;…

Vue环境搭建:vue+idea

目录 第一章、Vue环境搭建&#xff1a;安装node2.1&#xff09;node的下载2.2&#xff09;配置node的环境变量2.3&#xff09;常见的npm命令 第二章、使用idea创建vue工程2.1&#xff09;在IDEA中设置国内镜像2.2&#xff09;在IDEA中进行脚手架安装2.3&#xff09;在IDEA中创建…

银河麒麟v10(arm架构)部署Embedding模型bge-m3【简单版本】

硬件 服务器配置&#xff1a;鲲鹏2 * 920&#xff08;32c&#xff09; 4 * Atlas300I duo卡 参考文章 https://www.hiascend.com/developer/ascendhub/detail/07a016975cc341f3a5ae131f2b52399d 鲲鹏昇腾Atlas300Iduo部署Embedding模型和Rerank模型并连接Dify&#xff08;自…

轻量级碎片化笔记memos本地NAS部署与跨平台跨网络同步笔记实战

文章目录 前言1. 使用Docker部署memos2. 注册账号与简单操作演示3. 安装cpolar内网穿透4. 创建公网地址5. 创建固定公网地址 推荐 ​ 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站 前言…

【C++算法】54.链表_合并 K 个升序链表

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a; 题目链接&#xff1a; 23. 合并 K 个升序链表 题目描述&#xff1a; 解法 解法一&#xff1a;暴力解法 每个链表的平均长度为n&#xff0c;有k个链表&#xff0c;时间复杂度O(nk^2) 合并两个有序…

EG8200Mini-104边缘计算网关!聚焦IEC104协议的工业数据转换与远程运维平台

在工业自动化和信息化融合不断深化的背景下&#xff0c;现场设备的数据采集与协议转换能力对系统集成效率与运维成本产生着直接影响。EG8200Mini-104边缘计算网关正是基于此需求场景设计&#xff0c;具备IEC104主从站双向支持能力&#xff0c;并配套远程运维与多网络接入方案&a…

python多线程+异步编程让你的程序运行更快

多线程简介 多线程是Python中实现并发编程的重要方式之一&#xff0c;它允许程序在同一时间内执行多个任务。在某些环境中使用多线程可以加快我们代码的执行速度&#xff0c;例如我们通过爬虫获得了一个图片的url数组&#xff0c;但是如果我们一个一个存储很明显会非常缓慢&…

各种场景的ARP攻击描述笔记(超详细)

1、ARP报文限速 上一章我们说过ARP报文也是需要上送CPU进行处理的协议报文,如果设备对收到的大量ARP报文全部进行处理,可能导致CPU负荷过重而无法处理其他业务。因此,在处理之前需要对ARP报文进行限速,以保护CPU资源。 1.根据源MAC地址或源IP地址进行ARP限速 当设备检测到某一…

庙算兵推:使用Streamlit框架构建了一个智能作战推演系统。

这段代码是一个完整的军事模拟应用&#xff0c;使用Streamlit框架构建了一个智能作战推演系统。该系统包括了三维地图显示、作战单位管理、应急事件处理等功能。用户可以通过界面控制推演的开始和暂停&#xff0c;调整时间加速倍率&#xff0c;并查看实时的战斗情况和系统状态。…

HDCP(四)

HDCP驱动开发实战深度解析 以下从协议栈架构、核心模块实现、安全设计到硬件集成&#xff0c;结合HDCP 2.x规范与主流硬件平台&#xff08;如ARM、FPGA&#xff09;特性&#xff0c;系统拆解驱动开发关键环节&#xff1a; 1. 协议栈架构与模块划分 驱动分层设计 硬件抽象层&…

Docker MySQL的主从同步 数据备份 数据同步 配置文件

创建主库 docker run \--namemysql_1 \-e MYSQL_ROOT_PASSWORD123456 \-p 3306:3306 \-v mysql_main_data:/var/lib/mysql \--restart unless-stopped \-d \mysql:8.0进入容器内部 docker exec -it mysql_1 bash查找配置文件 find / -name my.cnf复制出主机 docker cp mysql…

996引擎-疑难杂症:Ctrl + F9 编辑好的UI进入游戏查看却是歪的

Ctrl F9 编辑好UI后&#xff0c;进入游戏查看却是歪的。 检查Ctrl F10 是否有做过编辑。可以找到对应界面执行【清空】