[C + +] leetcode:113 Word break II (DP && backtacking) solution split combination

Source: Internet
Author: User

Topic:

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

Return all such possible sentences.

for example, given
s  = " Catsanddog ",
dict  = < Code style= "Font-family:menlo,monaco,consolas, ' Courier New ', monospace; font-size:13px; PADDING:2PX 4px; Color:rgb (199,37,78); Background-color:rgb (249,242,244) ">[" Cat "," Cats "," and "," sand "," dog "] .

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

Answer 1:BF Recursive Solution TLE

idea: each time you maintain a current result set, and then iterate through all the remaining substrings, if the substring appears in the dictionary, save the result. And put all the remaining characters in the next layer recursively.

However, this practice will time out in Leetcode.

Error Code:

Class Solution {public:    vector<string> wordbreak (string s, unordered_set<string> &dict) {        vector<string> ret;        if (s.size () = = 0) return ret;        Wordbreak_helper (S, dict, 0, "", ret);        return ret;    }    Private:    void Wordbreak_helper (string s, unordered_set<string>& dict, int pos, string tmp, vector< string>& ret)    {        if (pos = = S.size ())        {            ret.push_back (tmp.substr (0, Tmp.size ()-1));  Remove space            return;        }                for (int i = pos; i < S.size (), i++)        {for            (int j = 1; J < S.size ()-I; + j)            {                string substr = s.su BSTR (POS, j);                if (Dict.find (substr)! = Dict.end ())                {                    Wordbreak_helper (S, Dict, i+1, tmp + "" + substr, ret);                }            }        }    }};

Answer 2: Join DP

idea: This problem, we learn from word break in the dynamic planning ideas. But this time we need to record each split result, so we use a two-dimensional array to save dynamic programming results, two-dimensional array form vector<list<int>> DP, Dp[i] to represent the string from the coordinate i The list of terminating positions for all legal words that begin. We start from the end of the string, from the bottom up to solve the dynamic layout of the array, we take the current stop as the terminating position, loop all the legal start position, if the substring in the dictionary, the corresponding in the DP array to add elements. It is important to note that if there are no matching dictionary words from the current stop (the description is not broken here), you can skip this stop as a cutoff position.

After solving all possible combinations, we use backtracking to solve all possible segmentation situations. This time from top to bottom, start with the string header and iterate through all the results until the end of the string is reached.

Attention:

1. Stop means the last bit of the end of the word, that is, the first or string length of the next word. So stop starts with s.size ().

for (int stop = S.size (); stop >= 0; stop--)
2. If there are no dictionary words starting from the current stop, you can skip this breakpoint.

If there are no matching words starting from stop, you can skip the stop word that examines this stops coordinate (stop indicates the last digit of the word)            if (Stop < S.size () && Mark[stop].empty ( )) continue;
3. Starting from the current stop, loop through all legitimate start positions and update the dynamic Plan array.

/check all words in the dictionary before the current stop cutoff, and add them into mark. For            (int start = stop-1; start >= 0; start--)            {                String substr = S.substr (start, stop-start);                if (Dict.find (substr)! = Dict.end ())                {                    mark[start].push_back (stop);}            }
4. New usage of c++11 for.

The For statement will allow a simple range iteration:

intMy_array[5] = {1,2,3,4,5}; for (int &X:My_array){X*= 2;}

for The first part of the definition of the sentence is used to make the parameters of the range iteration, just like the parameters declared in the general for loop, whose scope is only the scope of the loop. The second block after the ":" represents the range that will be iterated. Also, a loop variable is a reference that can change its value in a loop.

For (int& Stop:mark[index])

In the program, this sentence represents the stop position of all the words starting with index.

5. When backtracking, we note that to maintain the current path, you cannot replace the path with a new string that adds a substring, because this is a looping statement, and we will still use the original path for the next stop (no substring added).

For (int& Stop:mark[index])        {            string substr = S.substr (index, stop-index);            String NewPath = Path + (index = = 0? substr: "" + substr);
AC Code:

Class Solution {public:vector<string> Wordbreak (string s, unordered_set<string> &dict) {//mark        [I] stores all the cutoff coordinates of a word in the dictionary, starting with the I coordinate.                Vector<list<int>> Mark (S.size (), list<int> ()); From the end of the string to the head for (int stop = S.size (); stop >= 0; stop--) {//If there are no matching words starting from stop, you can skip the closing order to review this stop coordinate            The word (stop indicates the last digit of the word) if (Stop < S.size () && mark[stop].empty ()) continue;            Check all the words in the dictionary before the current stop cutoff, and add them into mark. for (int start = stop-1; start >= 0; start--) {String substr = S.substr (Start, Stop-start                );                if (Dict.find (substr)! = Dict.end ()) {mark[start].push_back (stop);        }}} vector<string> ret;        Generate (Mark, 0, S, "", ret);    return ret; }private:void Generate (vector<list<int>> mark, int index, const string& s, stringPath, vector<string>& ret) {for (int& Stop:mark[index]) {string substr = s.su            BSTR (Index, STOP-INDEX);            String NewPath = Path + (index = = 0? substr: "" + substr);            if (stop = = S.size ()) Ret.push_back (NewPath);        else generate (Mark, stop, S, NewPath, ret); }    }};

This problem is very comprehensive, it is difficult to combine DP and backtracking, especially the method of setting up DP array can be used for reference.




[C + +] leetcode:113 Word break II (DP && backtacking) solution split combination

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.