• [LeetCode] Word Break II


    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"].

    Hide Tags
     Dynamic Programming Backtracking
     
     

    方法一:

    DFS,

    start已知,当start超过str长度时,说明全部字符串都能找到了。。

    小数据可过,大数据时超时

    class Solution {
        private:
            // DFS
            void wordBreak(string s, int start, unordered_set<string> & dict)
            {
                size_t size =  s.size();
                if(size == 0)
                    return;
                if(start >= size)
                {
                    string tmpStr;
                    for(int i = 0; i < m_str.size(); i++)
                    {
                        if(i == m_str.size() - 1)
                            tmpStr += m_str[i];
                        else
                            tmpStr += m_str[i] + " ";
                    }
                    m_strs.push_back(tmpStr);
                }
    
                for( int i = start; i <size; i++)
                {
                    string str = s.substr(start, i-start+1);
                    if(dict.find(str) != dict.end())
                    {
                        m_str.push_back(str);
                        wordBreak(s,i+1, dict);
                        m_str.pop_back();
                    }
    
                }
            }
    
        public:
            vector<string> wordBreak(string s, unordered_set<string>& wordDict) {
                m_str.clear();
                m_strs.clear();
    
                wordBreak(s,0, wordDict);
    
                return m_strs;
            }
       private:
            vector<string> m_str;
            vector<string> m_strs;
    };

    方法二:

    长度为 n 的字符串有 n+1 个隔板

    基于dp之后,使用 vector<vector<string> > map 来保存当前的划分,

    map[i] = {map[j]中原有的划分字符串} + s[j+1, i],if s[j+1, i] 存在于字典中,

    具例子,

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

    map[7] = {"cat sand", "cats and""}

    map[10] = {"cat sand dog", "cats and dog"}, dog 在字典中。

    但是 Status: Memory Limit Exceeded,头一次遇到这个错误。

            vector<string> wordBreak2(string s, set<string> &dict) {
                vector<bool> f(s.size() + 1, false);
                vector<string> tmpStrVec;
                vector<vector<string> > map(s.size()+ 1, tmpStrVec);
                f[0] = true;
                for (int i = 1; i <= s.size(); ++i)
                {
                    for (int j = i - 1; j >= 0; --j)
                    {
                        string subStr = s.substr(j, i-j);
                        if (f[j] && dict.find(subStr) != dict.end())
                        {
                            f[i] = true;
                            vector<string> strVec = map[j];
                            if(strVec.size() == 0)
                            {
                                strVec.push_back(subStr);
                                map[i] = strVec;
                            }
                            else
                            {
                                for(int k = 0; k < strVec.size(); k++)
                                {
                                    strVec[k] += " " + subStr ;
                                    map[i].push_back(strVec[k]);
                                }
                            }
                        }
                    }
                }
                return map[s.size()];

    方法三: 这题不能直接DFS,否则会超时,联想到上一题,可以跟上题一样先动态规划,判断能否被break,如果s不能被break,那么也没有DFS的必要

    class Solution {
        public:
            void breakWord(vector<string> &res, string &s, unordered_set<string> &dict, string str, int start, vector<bool> &f) {
    
                if(f[start] == false) return ;
                if(start >= s.size())
                    res.push_back(str);
    
    
                for(int i = start; i <s.size(); i++)
                {
                    string subStr = s.substr(start, i-start + 1);
                   // cout <<"i 	" <<i << "	j	" << i-start<<"	"<<subStr << endl;
                    if(dict.count(subStr))
                    {
                        if(str.empty())
                            breakWord(res,s,dict, subStr, i+1,f);
                        else
                            breakWord(res,s,dict, str+" "+subStr, i+1,f);
                    }
    
                }
            }
    
            vector<string> wordBreak(string s, unordered_set<string> &dict) {
                vector<bool> f(s.size() + 1, false);
                f[0] = true;
                for (int i = 1; i <= s.size(); ++i) {
                    for (int j = i - 1; j >= 0; --j) {
                        if (f[j] && dict.find(s.substr(j, i - j)) != dict.end()) {
                            f[i] = true;
                            break;
                        }
                    }
                }
    
                vector<string> res;
                if (f[s.size()])
                    breakWord(res, s, dict, "", 0, f);
                return res;
            }
    };
  • 相关阅读:
    C常用字符字符串处理函数
    ipmotool
    It旅程经典报错信息
    带外监控
    zookeeper工作原理解析
    浅析MySQL各种索引
    osx下查看jar文件
    TopCoder SRM624 BuildingHeightEasy 题解
    ViewPager切换动画效果改动
    vim中的高亮全部同样单词的方法
  • 原文地址:https://www.cnblogs.com/diegodu/p/4560937.html
Copyright © 2020-2023  润新知