> 技术文档 > 动态规划 —— 子数组系列-单词拆分_动态规划】单词的划分

动态规划 —— 子数组系列-单词拆分_动态规划】单词的划分


1. 单词拆分

题目链接:

139. 单词拆分 - 力扣(LeetCode)icon-default.png?t=O83Ahttps://leetcode.cn/problems/word-break/description/

 


2. 算法原理 

状态表示:以某一个位置为结尾或者以某一个位置为起点

  

dp[i]表示:在[0,i]区间里的字符串,能否被字典中的单词拼接而成

  

如果可以拼接而成那么里面存储的是一个true,如果不能拼接而成那么里面存储的是一个false

  

这里可以看出本题是一个bool类型的值

  

2. 状态转移方程:根据最后一个位置来划分问题

  

本题最后一个位置就是最后一个单词,要么就是最后一个字符来构成最后一个单词,要么就是最后两个字符来构成最后一个单词.....,要么是整个字符串构成最后一个单词

     

我们可以将整个区间划分为俩部分:前面的那一部分能够拼接而成并且后面的那一部分是在字典中,那么整个的字符串就能够拼接而成

  

  

那么这样的话我们就可以设一个j,j表示最后一个单词起始位置的下标        0 < j < i 

 

  

 dp[i]分为两种情况:1. dp[j - 1] ==true && s(j~i)是否在字典中

   

                                   2. false

3. 初始化 :把dp表填满不越界,让后面的填表可以顺利进行

  

这里我们需要 加上一个虚拟节点,因为如果是整个字符串构成最后一个单词的情况的话,那么j - 1 就会越界

  

教给大家一个关于字符串类型题目的下标映射解决方法,我们可以在原字符串前面加上一个新的字符(随便什么,一般是空格),然后再赋值给字符串,这个时候就相当于原字符串是从1开始计数,就不用再统一往后移一位了

  

4. 填表顺序 

  

本题的填表顺序是:从左往右

5. 返回值 :题目要求 + 状态表示     

    

本题的返回值是:dp[n]


3.  代码 

动态规划的固定四步骤:1.  创建一个dp表

                                        2. 在填表之前初始化

                                        3. 填表(填表方法:状态转移方程)

                                        4. 确定返回值

class Solution {public: bool wordBreak(string s, vector& wordDict) { //将字典中的单词全部插入到哈希表里 unordered_sethash; for(auto& s :wordDict) hash.insert(s); int n=s.size(); vectordp(n+1); //初始化 dp[0]=true; s=\' \'+s; //填表 for(int i=1;i=1;j--)//j表示最后一个单词起始位置的下标 { if(dp[j-1] && hash.count(s.substr(j,i-j+1)))//判断字串是否在字典中 {  dp[i]=true;  break; } } } return dp[n]; }};

未完待续~