算法学习day46

算法学习day46

  • 1.力扣 139.单词拆分
    • 1.1 分析
    • 1.2 代码
  • 2.参考资料

1.力扣 139.单词拆分

1.1 分析

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

说明:

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

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

1.确定dp数组以及下标的含义

dp[i]:字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词。

2.确定递推公式

如果确定dp[j]是true,且[j, i]这个区间的的子串出现在字典里,那么dp[i]一定是true。

递推公式: if([j ,i]这个区间的子串出现在字典里 && dp[j]是ture) 那么dp[i] = true。

3.dp数组如何初始化

dp[0]为true.

4.确定遍历顺序

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

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

本题是先遍历背包,在遍历物品。

5.举例推导dp[i]

算法学习day46_第1张图片

1.2 代码

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        // 将字典转换为unordered_set,便于快速查找
        unordered_set<string> wordSet(wordDict.begin(), wordDict.end());
        // dp数组,dp[i]表示s的前i个字符是否能被拆分成字典中的单词
        vector<bool> dp(s.size() + 1, false);
        // 初始化dp数组,空字符串可以被拆分成一个空单词
        dp[0] = true;
        // 遍历s的所有子串,寻找子串是否在字典中存在,并且前面的字符串也能被拆分成字典中的单词
        for (int i = 1; i <= s.size(); i++) {   // 遍历背包
            for (int j = 0; j < i; j++) {       // 遍历物品
                // 截取s的第j个字符到第i个字符组成的子串
                string word = s.substr(j, i - j); //substr(起始位置,截取的个数)
                // 如果字典中存在该子串,并且前面的字符串也能被拆分成字典中的单词,则dp[i]为true
                if (wordSet.find(word) != wordSet.end() && dp[j]) {
                    dp[i] = true;
                }
            }
        }
        // 返回dp[s.size()],表示s的前s.size()个字符能否被拆分成字典中的单词
        return dp[s.size()];
    }
};

2.参考资料

[代码随想录]

你可能感兴趣的:(算法,动态规划,c++,数据结构,leetcode)