稀碎从零算法笔记Day29-LeetCode:单词拆分

本文介绍了如何使用动态规划解决LeetCode上的字符串单词拆分问题,将问题转化为背包问题,通过dp数组判断给定字符串是否可以由字典中的单词拼接而成。
摘要由CSDN通过智能技术生成

死磕dp的第二天了

题型:dp,字符串,二维数组,背包类

链接:139. 单词拆分 - 力扣(LeetCode)

来源:LeetCode

题目描述

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true

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

题目样例

代码

测试用例

测试用例

测试结果

139. 单词拆分

已解答

中等

相关标签

相关企业

给你一个字符串 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后,然后就是老生常谈的dp[i]的含义:因为只要确认能否凑出来,dp[i]那就是“长度”为 i 的串在字典中能否凑出来?同时我们不能【顾头不顾腚】—— j 和 i这一块的字符串也得看一下字典中有没有

于是dp[i] = dp[j]&(substr(j,i-j)!=std::find(wd.begin(),wd.end(),str))//当然,这一步创一个无序集合,可读性会更好些

笔者感觉不好理解的点是substr截取的长度是 【i-j】而不 +1 ,笔者感觉和 i 从1开始走有关

C++代码

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        // 老实dp
        int slen = s.length(),wdnum = wordDict.size();
        // dp[i]的含义:长度为i的字符串,能否找到字典中的单词
        //dp[i] :要看 ①dp[j] = 1(j是i前面的指针),说明前j个位置能从字典中查到 ②[j,i]的字符串在字典中有
        vector<bool> dp(slen + 1 , 0);
        dp[0] = 1;
        for(int i=1;i< slen+1;i++)
        {
            for(int j=0;j<i;j++)
            {
                // 长度是i-j,因为
                string temp = s.substr(j,i-j);
                if(dp[j] == 1 && std::find(wordDict.begin(),wordDict.end(),temp)!= wordDict.end())
                    dp[i] = 1;
            }
        }
        return dp[slen];
    }
};

结算页面

还得继续沉淀下

  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值