LeetCode(140) Word Break II

5303 단어 dpDFS
제목은 다음과 같습니다.
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"].
분석은 다음과 같습니다.
제목은 trie로 할 수도 있고 DP + DFS로 할 수도 있습니다.
먼저 DP + DFS 의 접근 방식을 살펴보겠습니다.
먼저 Word Break I와 유사하게 DP를 사용하여 입력 string이 Break에 허용되는지 여부를 판단하고 중간 결과를 기록합니다.이 중간 결과는 모든 전구 하표를 기록하고 다음 DFS의 기초이며 다음에 자세하게 설명한다.
그리고word ladder II의 모든 경로를 구하는 사상을 빌려 중간 결과에 대해 dfs를 해서 모든 경로를 찾습니다.
이제 중간 결과를 말씀드리겠습니다. 
먼저 아래의 예를 보아라.
s = "catsand", dict = ["cat", "cats", "and", "sand", ]. 그럼, 나는 하나의 수조result 를 사용하고 싶다.node로 기록하고 마지막resultnode[length-1]break가 가능하면 어느 점에서부터 마지막까지 break를 시작할 수 있습니다.length(s) = 7
result_node[6] = {2, 3}, 
cats에서 구분할 수 있기 때문에 "catsand"= "cats"+ "and"
캣에서 나눌 수도 있어요.'캣산드'='캣'+'산드'
즉, 마지막으로 길을 구할 때'd'노드(index=6)의 앞 노드는's'노드(index=3) 또는't'노드(index2)이다. 
다음 0이 시작되면 현재 아래 j를 끝으로 하는 하위 문자열이 디렉터리에 있습니다. 현재 아래 문자열의 선구를 -1로 기억하고 선구 집합에 계산합니다.예를 들어'catsand'아래에't'를 표시하면'cat'가 디렉터리에 있기 때문에resultnode[2]=-1, 동리resultnode[3] = -1;
비교적 번거로운 예를 하나 더 보아라.
unordered_set dict = {"a", "aa"};
string s                          =            "aaaa";
result_node[0]               =            {-1};
result_node[1]               =            {-1, 0};
result_node[2]               =            {0, 1};
result_node[3]               =            {1, 2};
이제 DP를 사용하여 입력 문자를 처음부터 끝까지 한 번 훑어보고 각 노드의 선구자를 기록하고 마지막으로 DFS를 진행하여 요구하는 형식에 따라 결과를 출력하면 된다.
틀리기 쉬운 점은 -1이라는 선구를 기록했기 때문에 마지막 dfs를 할 때 이 특수값을 주의해야 한다는 것이다.코드를 보십시오.
내 코드:
//30ms
class Solution {
public:
    void dfs(vector<vector<int> > & result_node, int start, vector<int> & path, vector<vector<int> > &paths) {
        if (start == -1) {
            
            // BUG1:
            // C++ pass by value, so first insert into paths, then edit(pop_back(),which holds the value -1) the value of path. 
            // If pop_back() path happens before it is inserted into the paths, then the next round in dfs will be affected.
            paths.push_back(path);
            paths.back().pop_back();
            reverse(paths.back().begin(), paths.back().end());
            return;
        } else {
            for (int i = 0; i < result_node[start].size(); ++i) {

                // BUG2:
                // path.push_back(i);
                path.push_back(result_node[start][i]);
                dfs(result_node, result_node[start][i], path, paths);
                path.pop_back();
            }
        }
    }
    void format_result(string &s ,vector<vector<int> > &paths, vector<string> &final_paths) {
        for (int i = 0; i < paths.size(); ++i) {
            
            // BUG3:
            // the first component of the word string is simply the first word
            // the last delimiter(as in the example, it should be ) should be inserted
            paths[i].push_back(s.length() -1);
            string tmp = s.substr(0, paths[i][0] + 1); 
            
            // BUG4:
            // the second component of the word string is the space sign " " and the word.
            for (int j = 1;j < paths[i].size(); ++j) {
                tmp += " ";
                tmp += s.substr(paths[i][j - 1] + 1, paths[i][j] - paths[i][j - 1]);
            }
            final_paths.push_back(tmp);
        }
    }
    vector<string> wordBreak(string s, unordered_set<string> &dict) {
        vector<bool> result_bool(s.length(), false);
        vector<vector<int> > result_node(s.length());
        vector<string> final_paths;
        if (dict.empty()) return final_paths;
        if (dict.find(s) != dict.end()) {
            final_paths.push_back(s);
            return final_paths;
        }
        for (int i = 0; i < result_bool.size(); ++i) {
            if (dict.find(s.substr(0, i + 1)) != dict.end()) {
                result_bool[i] = true;
                result_node[i].push_back(-1);
            }
            for (int j = 0; j < i; ++j) {
                if ((result_bool[j] == true) && (dict.find(s.substr(j + 1, i -j))!= dict.end())) {
                    result_bool[i] = true;
                    result_node[i].push_back(j);
                }
            }
        }
        vector<vector<int> > paths;
        
        // BUG5:
        // similar to Word Break I, use a bool array to record if the word can be segmented.
        // before dfs, should test whether dfs is needed
        if ( !result_bool[s.length() - 1]) {
            return final_paths;
        }
        
        vector<int> path;
        dfs(result_node, result_node.size() - 1, path, paths);
        format_result(s, paths, final_paths);
        return final_paths;
    }
};

좋은 웹페이지 즐겨찾기