LeetCode——work-break-ii(140)

Given a non-empty string s and a dictionary wordDict containing a list of non-empty words, add spaces in s to construct a sentence where each word is a valid dictionary word. Return all such possible sentences.

Note:

  • The same word in the dictionary may be reused multiple times in the segmentation.
  • You may assume the dictionary does not contain duplicate words.

Example 1:

Input:
s = "catsanddog"
wordDict = ["cat", "cats", "and", "sand", "dog"]
Output:
[
  "cats and dog",
  "cat sand dog"
]

Example 2:

Input:
s = "pineapplepenapple"
wordDict = ["apple", "pen", "applepen", "pine", "pineapple"]
Output:
[
  "pine apple pen apple",
  "pineapple pen apple",
  "pine applepen apple"
]
Explanation: Note that you are allowed to reuse a dictionary word.

Example 3:

Input:
s = "catsandog"
wordDict = ["cats", "dog", "sand", "and", "cat"]
Output:
[]

分析:

比1难的地方是要列出所有可能,不过有work-breaki的基础,啥都好说。

1详见:work-break-i

下面代码可行,但是内存超了,囧~,思路应该差不多,小伙伴们结合work-break-i看看吧

vector<string> wordBreak(string s, unordered_set<string> &dict) {
    vector<vector<string>> stable(s.size()+1);
    vector<bool> table(s.size()+1, false);
    table[0]=true;
    stable[0].push_back("");

    bool flag;
    for(int i=1;i<=s.size();++i)
    {
        flag = false;
        for(int j=0;j<i;++j)
        {
            table[i] = table[j]&&(dict.find(s.substr(j,i-j))!=dict.end());
            if(table[i]==true)
            {
                flag = true;
                for(int k=0;k<stable[j].size();++k)
                {
                    if(stable[j][k]!="")
                        stable[i].push_back(stable[j][k]+" "+s.substr(j,i-j));
                    else
                        stable[i].push_back(s.substr(j,i-j));
                }
            }
        }
        table[i] = flag;
    }
    return stable[s.size()];
}

上面代码内存超限,分析是因为表里存了太多重复的字符串了,于是我改成了表是只存哪个j能够让f(i)=f(j)&&f(j+1,i)为true,到了返回的时候用递归将结果算出来再返回。

class Solution {
public:
    
    vector<string> GetString(vector<vector<int>> &stable, int index, string& s)
{
    vector<string> res, last;
    if(index == -1)
    {
        res.push_back("");
        return res;
    }
    for(int i=0;i<stable[index].size();++i)
    {
        last = GetString(stable, stable[index][i], s);
        string temp;
        if(stable[index][i]!=-1)
        temp = s.substr(stable[index][i], index - stable[index][i]);
        else
            temp ="";
        cout<<temp<<endl;
        for(int k=0;k<last.size();++k)
        {
            if(last[k]!="")
                res.push_back(last[k]+" "+temp);
            else
                res.push_back(temp);
        }
    }
    return res;
}
    
    vector<string> wordBreak(string s, vector<string>& wdict) {
        unordered_set<string> dict;
        for(int i=0;i<wdict.size();++i)
            dict.insert(wdict[i]);
      vector<bool> table(s.size()+1, false);
    table[0]=true;
   // stable[0].push_back("");
    vector<vector<int>> stable(s.size()+1);
    stable[0].push_back(-1);
    bool flag;
    for(int i=1;i<=s.size();++i)
    {
        flag = false;
        for(int j=0;j<i;++j)
        {
            table[i] = table[j]&&(dict.find(s.substr(j,i-j))!=dict.end());
            if(table[i]==true)
            {
                flag = true;
                stable[i].push_back(j);
            }
        }
        table[i] = flag;
    }

    return GetString(stable, s.size(), s);
    }
};

臃肿了不少,但是能过,还是ok的...接下来是看别人代码的环节,思路大同小异,唯一的差别是,这份代码最后构造字符串的时候是从前往后构造的,每次构造都要查表,如果新词在表里,就把他加入到res 里。还有就是确实代码写得不错,比我的烂代码节省不少无谓的计算,QAQ。

class Solution {
private:
    unordered_set<string> words;

public:
    vector<string> wordBreak(string s, vector<string>& wordDict) {
        words.clear();
        copy(wordDict.begin(), wordDict.end(), inserter(words, words.end()));

        int n = s.size();
        vector<int> dp(n + 1, 0);
        dp[0] = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = i - 1; j >= 0; --j) {
                if (dp[j]) {
                    if (words.count(s.substr(j, i - j))) {
                        dp[i] = 1;
                        break;
                    }
                }
            }
        }

        vector<string> res;
        if (dp[n]) {
            constructSentence(s, dp, 0, res, "");
        }
        return res;
    }

    void constructSentence(const string& s,
                           const vector<int>& dp,
                           int pos,
                           vector<string>& res,
                           string temp) {
        for (int i = pos + 1; i < dp.size(); ++i) {
            if (dp[i]) {
                string new_word = s.substr(pos, i - pos);
                if (words.count(new_word)) {
                    if (i + 1 == dp.size()) {
                        res.push_back(temp + new_word);
                        return;
                    }
                    constructSentence(s, dp, i, res, temp + new_word + " ");
                }
            }
        }
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值