leetcode 139. Word Break 、140. Word Break II

139. Word Break

字符串能否通过划分成词典中的一个或多个单词。

使用动态规划,dp[i]表示当前以第i个位置(在字符串中实际上是i-1)结尾的字符串能否划分成词典中的单词。

j表示的是以当前i的位置往前找j个单词,如果在j个之前能正确分割,那只需判断当前这j单词能不能在词典中找到单词。j的个数不能超过词典最长单词的长度,且同时不能超过i的索引。

初始化时要初始化dp[0]为true,因为如果你找第一个刚好匹配成功的,你的dp[i - j]肯定就是dp[0]。因为多申请了一个,所以dp中的i相当于s中的i-1。

s.substr(i-j,j)实际上是s.substr(i-j + 1 - 1,j),因为本身应该提取i - j +1,但因为dp位置比s多一个,所以还要-1。

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        int length = 0;
        for(string word : wordDict){
            if(word.size() > length)
                length = word.size();
        }
        vector<bool> dp(s.size() + 1,false);
        dp[0] = true;
        for(int i = 1;i <= s.size();i++){
            for(int j = 1;j <= length && j <= i;j++){
                if(dp[i-j]){
                    string str = s.substr(i-j,j);
                    for(string word : wordDict){
                        if(word == str){
                            dp[i] = true;
                            break;
                        }
                    }
                }
            }
        }
        return dp[s.size()];
    }
};

140. Word Break II

一个字符串加空字符串还是原字符串

class Solution {
public:
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        unordered_map<string, vector<string>> m;
        return helper(s, wordDict, m);
    }
    vector<string> helper(string s, vector<string>& wordDict, unordered_map<string, vector<string>>& m) {
        if (m.count(s)) return m[s];
        if (s == "") return {""};
        vector<string> res;
        for (string word : wordDict) {
            if (s.substr(0, word.size()) != word) continue;
            vector<string> rem = helper(s.substr(word.size()), wordDict, m);
            for (string str : rem) {
                res.push_back(word + (str.empty() ? "" : " ") + str);
            }
        }
        m[s] = res;
        return res;
    }
};
原文地址:https://www.cnblogs.com/ymjyqsx/p/10943797.html