(转载)leetcode日题 139.单词拆分

动态规划


思路和算法我们定义 dp[i] 表示字符串 s 前 i 个字符组成的字符串 s[0..i−1] 是否能被空格拆分成若干个字典中出现的单词。从前往后计算考虑转移方程,每次转移的时候我们需要枚举包含位置i−1 的最后一个单词,看它是否出现在字典中以及除去这部分的字符串是否合法即可。公式化来说,我们需要枚举 s[0..i−1] 中的分割点 j ,看 s[0..j−1] 组成的字符串s1​ (默认 j=0 时 s1为空串)和 s[j..i−1] 组成的字符串s2是否都合法,如果两个字符串均合法,那么按照定义s1和 s2拼接成的字符串也同样合法。由于计算到 dp[i] 时我们已经计算出了dp[0..i−1] 的值,因此字符串 s1是否合法可以直接由dp[j] 得知,剩下的我们只需要看 s2是否合法即可,因此我们可以得出如下转移方程:

dp[i]=dp[j] && check(s[j..i−1])

其中 check(s[j..i−1]) 表示子串 s[j..i−1] 是否出现在字典中。

对于边界条件,我们定义dp[0]=true 表示空串且合法。

 

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        auto wordDictSet = unordered_set <string> ();
        for (auto word: wordDict) {
            wordDictSet.insert(word);
        }

        auto dp = vector <bool> (s.size() + 1);
        dp[0] = true;
        for (int i = 1; i <= s.size(); ++i) {
            for (int j = 0; j < i; ++j) {
                if (dp[j] && wordDictSet.find(s.substr(j, i - j)) != wordDictSet.end()) {
                    dp[i] = true;
                    break;
                }
            }
        }

        return dp[s.size()];
    }
};

 

 

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/word-break/solution/dan-ci-chai-fen-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

posted @ 2020-11-01 16:49  悲惨痛苦太刀  阅读(68)  评论(0编辑  收藏  举报