动态规划——单词拆分

本文详细阐述了如何通过动态规划解决一个编程问题,涉及将给定字符串s拆分成字典wordDict中的单词。使用dp数组和背包模型模拟拆分过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

力扣题目链接(opens new window)

给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

说明:

拆分时可以重复使用字典中的单词。

你可以假设字典中没有重复的单词。

示例 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

想要用动态规划的方法做,先得把列表 wordDict放到一个包中,

       unordered_set<string> wordset(wordDict.begin(),wordDict.end());

即把 wordDict放到wordset中,

然后开始确定递推公式,这里我们使用这个思想——把s中的字母循环后,确定到第几个字母,截取的单词符合wordDict,然后把这个字母打上j的标记,然后再从j字母开始,到下一个能截取单词并符合wordDict,这样我们可以直接从后面开始,不需要一遍一遍的遍历了

 if (wordSet.find(word) != wordSet.end() && dp[j]) {
                    dp[i] = true;

然后就可以准备初始化了,首先dp[0]的含义,我们使用的是默认数组是false,后面通过是否为true来判断可否拆分为wordDirt中的单词,所以一开始的dp[0]得定义成true。

于是所有的代码为

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
        vector<bool> dp(s.size() + 1, false);
        dp[0] = true;
        for (int i = 1; i <= s.size(); i++) {   // 遍历背包
            for (int j = 0; j < i; j++) {       // 遍历物品
                string word = s.substr(j, i - j); //substr(起始位置,截取的个数)
                if (wordSet.find(word) != wordSet.end() && dp[j]) {
                    dp[i] = true;
                }
            }
        }
        return dp[s.size()];
    }
};

这个题目用背包问题理解,就是把s理解成背包,wordDict中的一个一个单词理解成物品,物品是可以无限使用的,问题是,我能否用一个个单词把s背包填满,是则返回true,否则返回false。

但值得注意的一点是这个s背包在放物品时必须时按照s中单词的顺序来的,所以我们必须先遍历 背包,再遍历物品。

如果求组合数就是外层for循环遍历物品,内层for遍历背包

如果求排列数就是外层for遍历背包,内层for循环遍历物品

此题便是求排列数。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值