Word Break II (LeetCode)

Question:

https://oj.leetcode.com/problems/word-break-ii/

 

解答:

跟Word Break类似,只不过把bool变量变成vector<int>,保存所有能够跟当前点形成一个有效word的点,并且那个点本身的vector<int>不为空(等同于bool flag = true)。所以我们从点(n-1)开始回溯,就能遍历所有点。

比如:

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

我们就能得到如下的vector<int>:

index  vector<int>

0('c')    {}

1('a')    {}

2('t')    {-1} 

3('s')    {-1}

4('a')    {}

5('n')    {}

6('d')    {2, 3}

7('d')    {}

8('o')    {}

9('g')    {6}

 

从9开始回溯,形成的组合就有:{6, 3, -1}, {6, 2, -1},这些值其实也就是相当于在原字符串往后插入空格的位置(省略-1).

遍历能用DFS, BFS,其中递归的BFS最容易写。

class Solution {
public:
    vector<string> wordBreak(string s, unordered_set<string> &dict) {

        vector<string> ret;
        
        int n = s.size();
        
        if (n==0)
            return ret;
        
        vector<vector<int>> prevWordEndsArray (n);
        
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j <= i; j++)
            {
                if ((j == 0 || prevWordEndsArray[j-1].size() > 0) && dict.find(s.substr(j, i-j+1)) != dict.end())
                    prevWordEndsArray[i].push_back(j-1);
            }
        }
        
        vector<int> vempty;
        BackTrace(prevWordEndsArray, n-1, s, ret, vempty);

        return ret;
    }
    
    
    void BackTrace(vector<vector<int>>& prevWordEndsArray, int arrayIndex, string& s, vector<string>& ret, vector<int>& breaks)
    {
        for (int i = 0; i < prevWordEndsArray[arrayIndex].size(); i++)
        {
            if (prevWordEndsArray[arrayIndex][i] == -1)
            {
                // found one
                AddBreaksToString(ret, s, breaks);
            }
            else
            {
                vector<int> newBreaks = breaks;
                newBreaks.push_back(prevWordEndsArray[arrayIndex][i]);
                
                BackTrace(prevWordEndsArray, prevWordEndsArray[arrayIndex][i], s, ret, newBreaks);
            }
        }
    }
    
    void AddBreaksToString(vector<string>& ret, string& s, vector<int>& breaks)
    {
        string wd = s;
        for (int i = 0; i < breaks.size(); i++)
        {
             // The value in breaks is from right to left
             wd.insert(breaks[i]+1, " ");
        }
        
        ret.push_back(wd);
    }
};

 

posted @ 2014-10-12 13:36  smileheart  阅读(152)  评论(0编辑  收藏  举报