【leetcode】Word Break II (hard)★

Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each word is a valid dictionary word.

Return all such possible sentences.

For example, given
s = "catsanddog",
dict = ["cat", "cats", "and", "sand", "dog"].

A solution is ["cats and dog", "cat sand dog"].

思路:

我自己用回溯做超时了,直接看大神的20ms代码吧

主要是即考虑了从前向后的连接,也考虑了从后向前的连接。

class Solution {
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict)
{
    vector<vector<int>> flag(s.size() + 1, vector<int>());
    flag[0].push_back(0);
    for (int i = 1; i <= s.size(); i++) //当前判断字符串的结束位置的下一个位置 如i=1 表示结束位置是 s[0] 从前向后
    {
        for (int j = 0; j < i; j++) //当前判断的字符串的起始位置
        {
            if (!flag[j].empty() && dict.find(s.substr(j, i - j)) != dict.end()) //只有该单词前面的单词能够找到时才压入结果
            {
                flag[i].push_back(j); //flag[i]中存储 以i为结束位置的下一个位置的单词 的起始位置 如flag[2] 里面存储的都是以s[1]结束的单词的第一个字母的位置
            }
        }
    }
    vector<string> result;
    getResult(result, flag, s, s.size()); //从后向前找结果, 只有能够划分到最后一个字母的单词切割方式才考虑
    return result;
}

void getResult(vector<string> &result, vector<vector<int>> &flag, string s, int n)
{
    for (int j = 0; j < flag[n].size(); j++)
    {
        int i = flag[n][j];
        if (i == 0) //找到起始点了,压入划分的答案
        {
            result.push_back(s);
            continue;
        }
        s.insert(s.begin() + i, ' ');
        getResult(result, flag, s, i);
        s.erase(i, 1);
    }
}
};

我自己TLE的代码,我只考虑了从前向后,非常繁琐。但具体为什么会慢那么多我还没想明白。仅仅是因为没有考虑从后向前吗?

class Solution {
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        vector<vector<bool>> issubstr(s.size(), vector<bool>(s.size(), false));
        for(int i = 0; i < s.size(); i++)
        {
            for(int j = 1; j <= s.length() - i; j++)
            {
                if((find(dict.begin(), dict.end(), s.substr(i, j))) != dict.end())
                {
                    issubstr[i][i + j - 1] = true;
                }
            }
        }
        
        vector<string> ans;
        vector<string> X;
        vector<vector<string>> S(1);
        int k = 0;
        for(int i = 1; i <= s.length(); i++)
        {
            if(issubstr[0][i - 1])
            {
                S[k].push_back(s.substr(0, i));
            }
        }

        while(k >= 0)
        {
            while(!S[k].empty())
            {
                while(X.size() > k)
                {
                    X.pop_back();
                }
                X.push_back(S[k].back());
                S[k].pop_back();
                int Xtotallen = 0;
                vector<string>::iterator it;
                for(it = X.begin(); it != X.end(); it++)
                {
                    Xtotallen += it->length();
                }
                if(Xtotallen == s.length())
                {
                    string partans = X[0];
                    for(it = X.begin() + 1; it != X.end(); it++)
                    {
                        partans += " ";
                        partans += (*it);
                    }
                    ans.push_back(partans);
                }
                else
                {
                    k++;
                    if(S.size() <= k)
                    {
                        S.push_back(vector<string>());
                    }
                    for(int i = 1; i <= s.length() - Xtotallen; i++)
                    {
                        if(issubstr[Xtotallen][Xtotallen + i -1])
                        {
                            S[k].push_back(s.substr(Xtotallen, i));
                        }
                    }
                }
            }
            k--;
        }
        return ans;
    }
};
原文地址:https://www.cnblogs.com/dplearning/p/4248736.html