首页 > 其他分享 >「动态规划」如何解决单词拆分问题?

「动态规划」如何解决单词拆分问题?

时间:2024-06-23 20:32:35浏览次数:20  
标签:子串 单词 拆分 wordDict 动态 true dp 字典

139. 单词拆分icon-default.png?t=N7T8https://leetcode.cn/problems/word-break/description/

给你一个字符串s和一个字符串列表wordDict作为字典。如果可以利用字典中出现的一个或多个单词拼接出s则返回true。注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

  1. 输入:s = "leetcode",wordDict = ["leet", "code"],输出:true,解释:返回true因为"leetcode"可以由"leet"和"code"拼接成。
  2. 输入:s = "applepenapple",wordDict = ["apple", "pen"],输出:true,解释:返回true因为"applepenapple"可以由"apple" "pen" "apple"拼接成。注意,你可以重复使用字典中的单词。
  3. 输入:s = "catsandog":wordDict = ["cats", "dog", "sand", "and", "cat"],输出:false。

提示:1 <= s.length <= 300,1 <= wordDict.length <= 1000,1 <= wordDict[i].length <= 20,s和wordDict[i]仅由小写英文字母组成,wordDict中的所有字符串互不相同。


我们用动态规划的思想来解决这个问题。

确定状态表示:根据经验和题目要求,我们用dp[i]表示:以i位置为结尾的子串,能否被字典中的单词拼接

推导状态转移方程:如果以i位置为结尾的子串可以被字典中的单词拼接,那么一定分为前半部分和后半部分,后半部分是一个单词。我们用j遍历[0, i]的范围,如果有至少1个j同时满足:

  1. dp[j - 1] == true,即以j - 1位置为结尾的子串可以被拼接
  2. s的下标范围在[j, i]的子串在字典中

则dp[i] = true。如果没有1个j同时满足这2个条件,那么dp[i] = false

但是由于j的范围是[0, i],当j = 0时,j - 1 = -1,判断dp[j - 1]时会越界,我们需要处理一下。显然,当j = 0时,表示前半部分不存在,后半部分是子串的整体,此时只需判断条件2是否满足

初始化:根据状态转移方程,填dp表时不存在越界问题,不需要初始化

填表顺序:根据状态转移方程,显然应从左往右填表

返回值:根据状态表示,应返回dp[n - 1],其中n为字符串s的长度。

细节问题:dp表的规模和字符串s相同,均为1 x n。为了方便查找子串是否在字典中,可以先把字典中的所有字符串存储到哈希表中。

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        int n = s.size();
        unordered_set hash(wordDict.begin(), wordDict.end());

        // 创建dp表
        vector<bool> dp(n);

        // 填表
        for (int i = 0; i < n; i++) {
            for (int j = i; j >= 0; j--) {
                if ((j == 0 || dp[j - 1]) &&
                    hash.count(s.substr(j, i - j + 1))) {
                    dp[i] = true;
                    break;
                }
            }
        }

        return dp[n - 1];
    }
};

标签:子串,单词,拆分,wordDict,动态,true,dp,字典
From: https://blog.csdn.net/xiang_bolin/article/details/139904362

相关文章

  • 新兰动态图网站
    网页效果图轮播图效果图代码图新兰主页代码:<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title&g......
  • PostMan动态设置全局变量
    1.前言在开发过程中调试接口,一般都会使用PostMan。其中有几个变量可能是好几个接口共用的,就会出现频繁手动复制(ctrl+c)、粘贴(ctrl+v)的情况。这个过程得非常留意,生怕复制错了,或删减了某些东西,导致接口报错。总是这样复制就显得非常繁琐和麻烦了。那有没有办法可以让......
  • P2404 自然数的拆分问题
    #include<bits/stdc++.h>#include<math.h>#include<cmath>usingnamespacestd;intmain(){   intn;   cin>>n;   if(n==2)cout<<"1+1";   elseif(n==3){      cout<<"1+1+1"<<endl;     ......
  • Java学习 - 网络静态路由与动态路由 讲解
    网络畅通的条件数据报包有去有回网络中的路由器必须知道且只需要知道下一跳的地址【路由器只要知道下一跳地址就行,不必知道如何到达任意的路由器,因为如果要实现,路由表将非常非常巨大,这是不可能的】静态路由静态路由是指网络管理员手动构建路由器的路由表,告诉路由器下一跳......
  • 纯CSS制作3D动态相册【流星雨3D旋转相册】HTML+CSS+JavaScriptHTML5七夕情人节表白网
    这是程序员表白系列中的100款网站表白之一,旨在让任何人都能使用并创建自己的表白网站给心爱的人看。此波共有100个表白网站,可以任意修改和使用,很多人会希望向心爱的男孩女孩告白,生性腼腆的人即使那个TA站在眼前都不敢向前表白。说不出口的话就用短视频告诉TA吧~制作一个表......
  • 问题 I: 单词检查(Ⅰ)- 顺序表实现
    问题I:单词检查(Ⅰ)-顺序表实现题目描述许多应用程序,如字处理软件,邮件客户端等,都包含了单词检查特性。单词检查是根据字典,找出输入文本中拼错的单词,我们认为凡是不出现在字典中的单词都是错误单词。不仅如此,一些检查程序还能给出类似拼错单词的修改建议单词。例如字典......
  • leaflet动态更改wms瓦片请求参数
    需求https://leafletjs.cn/reference.html#tilelayer-wms官方文档这里说了可以添加自定义参数,但是这里的写法,值是固定的如果我们需要添加的参数的值是动态变化的,那么,直接写在options的方式固然是行不通的解决办法重写getTileUrl方法,可以选择继承TilelayerWMS重写一个类,也可......
  • 动态内存分配(C++)
    什么叫动态分配?动态分配的优点动态分配的语法解释动态分配的变量动态分配的数组动态分配的结构体参考什么叫动态分配?形象来说,动态分配就像是在一个大型购物广场中,你根据需要随时租用或归还一个店铺。程序运行时,如果需要更多空间来存储数据,就会向操作系统“租用”内......
  • 静态库与动态库
    参考链接:https://www.bilibili.com/video/BV1N84y1J7hC/?spm_id_from=333.337.search-card.all.click&vd_source=91219057315288b0881021e879825aa3静态库创建使用VS创建时,可以搜索静态库,实现了逻辑后,然后可以切换到release模式下点击生成解决方案后会生成lib文件使用使用时......
  • C语言---动态内存管理
    1.为什么要有动态内存分配指针+结构体+动态内存管理是学习数据结构的非常重要的知识intmain(){intn=0;//向内存申请一块空间---一个整型4个字节intarr[10]={0};//向内存中申请一块连续的空间--10个整型--40个字节return0;}这两种但是上述......