1. 程式人生 > 實用技巧 >(轉載)leetcode日題 139.單詞拆分

(轉載)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)
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。