字符串单词拆分 Word Break

来源:互联网 发布:抢报名的软件 编辑:程序博客网 时间:2024/05/06 22:22

问题一(判断能否进行单词拆分):给出一个字符串,问能否将其拆分为1或多个单词。单词表已给出。

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.

For example, given
s = "leetcode",
dict = ["leet", "code"].

Return true because "leetcode" can be segmented as "leet code".


思路:直观思路是递归尝试进行。但是超时。注意,递归尝试往往会重复把一件已经做过的事情做很多次。

而另外一个算法,动态规划,则是借助空间暂存结果,待到下次需要用的时候直接拿结果。这是递归和DP的重要区别。

递归和DP的重要相同点是,都存在子问题。

这道题用动态规划算法的话,会变得非常的快。


状态量H[i],表示字符串s的前i个字符组成的子串是否能够进行单词拆分。

递推关系:k from 0 to i-1,只要有一个k满足 H[k]==1 且 s[k...i-1]是一个单词。则表明H[i]是比H[k]多加了一个单词,因此H[i]等于1.

class Solution {public:bool wordBreak(string s, unordered_set<string> &dict) {int n = s.size();if(n ==0)return false;int H[n+1];//H[i]表示s中前i个字符是否能进行word breakmemset(H,0,sizeof(H));H[0] = 1;for(int i=1;i<=n;i++){for(int j=0;j<i;j++)if(H[j] == 1 && dict.find(s.substr(j,i-j)) != dict.end()){H[i] = 1;break;}}return (H[n]==1);}};


问题二(进行单词拆分):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"].


 思路:首先利用上面的动态规划方法判断能否进行拆分。然后利用backtrack方法生成所有组合。

class Solution {public:    vector<string> wordBreak(string s, unordered_set<string> &dict) {        vector<string> re;        int n = s.size();        if(n == 0)            return re;                int H[n+1];        memset(H, 0, sizeof(H));        H[0] = 1;        for(int i=1; i<=n;i++)        {            for(int j=0;j<i;j++)            {                if(H[j] == 1 &&  dict.find(s.substr(j, i-j)) != dict.end() )                {                    H[i] = 1;                    break;                }            }        }                if(H[n] == 0) // 先利用DP方法检验是否能够拆分单词            return re;        string now = "";        backtrack(s, now, 0, H, n, dict, re); //再用backtrack方法进行组合生成        return re;    }        void backtrack(string &s, string &now, int idx, int H[], int n, unordered_set<string> &dict, vector<string> &re)    {        if(idx == n)        {            re.push_back(now);            return;        }        for(int i=idx;i<n;i++)        {            if(H[i+1] == 1 && dict.find(s.substr(idx, i-idx+1)) != dict.end() )            {                string new_now;                if(now == "")                    new_now = s.substr(idx, i-idx+1);                else                    new_now = now + " " + s.substr(idx, i-idx+1);                backtrack(s, new_now, i+1, H, n, dict, re);            }        }    }    };


0 0
原创粉丝点击