LeetCode(140) 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"].
분석은 다음과 같습니다.
제목은 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
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;
}
};
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【경쟁 프로 전형적인 90문】008의 해설(python)의 해설 기사입니다. 해설의 이미지를 봐도 모르는 (이해력이 부족한) 것이 많이 있었으므로, 나중에 다시 풀었을 때에 확인할 수 있도록 정리했습니다. ※순차적으로, 모든 문제의 해설 기사를 들어갈 예정입니다. 문자열...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.