力扣算法——139WordBreakM

Posted 自由の翼

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣算法——139WordBreakM相关的知识,希望对你有一定的参考价值。

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

Note:

  • The same word in the dictionary may be reused multiple times in the segmentation.
  • You may assume the dictionary does not contain duplicate words.

Example 1:

Input: s = "leetcode", wordDict = ["leet", "code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

Example 2:

Input: s = "applepenapple", wordDict = ["apple", "pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
             Note that you are allowed to reuse a dictionary word.

Example 3:

Input: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
Output: false

Solution:
  使用动态规划进行求解
  这道题其实还是一道经典的 DP 题目,也就是动态规划 Dynamic Programming。博主曾经说玩子数组或者子字符串且求极值的题,基本就是 DP 没差了,虽然这道题没有求极值,但是玩子字符串也符合 DP 的状态转移的特点。把一个人的温暖转移到另一个人的胸膛... 咳咳,跑错片场了,那是爱情转移~ 强行拉回,DP 解法的两大难点,定义 dp 数组跟找出状态转移方程,先来看 dp 数组的定义,这里我们就用一个一维的 dp 数组,其中 dp[i] 表示范围 [0, i) 内的子串是否可以拆分,注意这里 dp 数组的长度比s串的长度大1,是因为我们要 handle 空串的情况,我们初始化 dp[0] 为 true,然后开始遍历。注意这里我们需要两个 for 循环来遍历,因为此时已经没有递归函数了,所以我们必须要遍历所有的子串,我们用j把 [0, i) 范围内的子串分为了两部分,[0, j) 和 [j, i),其中范围 [0, j) 就是 dp[j],范围 [j, i) 就是 s.substr(j, i-j),其中 dp[j] 是之前的状态,我们已经算出来了,可以直接取,只需要在字典中查找 s.substr(j, i-j) 是否存在了,如果二者均为 true,将 dp[i] 赋为 true,并且 break 掉,此时就不需要再用j去分 [0, i) 范围了,因为 [0, i) 范围已经可以拆分了。最终我们返回 dp 数组的最后一个值,就是整个数组是否可以拆分的布尔值了,代码如下:
 1 class Solution {
 2 public:
 3     bool wordBreak(string s, unordered_set<string> &dict) {
 4         vector<string> wordDict;
 5         unordered_set<string>dict;
 6         for (auto a : wordDict)
 7             dict.insert(a);
 8         vector<bool>dp(s.size() + 1, false);
 9         dp[0] = true;//边界
10         for(int i=0;i<dp.size();++i)
11             for(int j=0;j<i;++j)
12                 if (dp[j] && dict.count(s.substr(j, i - j)))//状态转移方程
13                 {
14                     dp[i] = true;
15                     break;
16                 }
17         return dp.back();
18     }
19 };

 

以上是关于力扣算法——139WordBreakM的主要内容,如果未能解决你的问题,请参考以下文章

单词拆分--力扣

2021-12-24:划分字母区间。 字符串 S 由小写字母组成。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。返回一个表示每个字符串片段的长度的列表。 力扣763。某大厂面试

代码随想录算法训练营day46|139.单词拆分 剑指Offer10-I.斐波那契数列 10-II.青蛙跳台阶问题

LeetCode 139. 单词拆分 | Python

ALGO-139_蓝桥杯_算法训练_s01串(递归)

力扣——算法入门计划第一天