[LeetCode] Word Break II 解题思路

时间:2023-11-27 23:28:26

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"].

这道题是 Word Break的一个拓展

问题:根据给的单词字典,求一个字符串所有可能的有效分割。

有了 Word Break 的经验,这道题做起来也顺畅了许多。

假设将字符串 s 分割为两段,[0,i-1], [i, n-1],如果[0, i-1] 为有效单词,[i, n-1]为有效单词集合,那么 s 就是一个有效字符串。将 [0, i-1] 依次和 [i, n-1] 所有可能分别匹配,则得到 s 以 i 为分割点得全部有效分割。

将 i 从 1 到 n-1 遍历一次,则求得 s 的全部分割的可能。

和 Word Break 一样,需要记录已计算的结果,提高效率。利用 map<int, vector<string>> idx_words[k] 来记录 [k, n-1] 子串的全部有效分割。

    map<int, vector<string>> idx_words;

    vector<string> match(string s, unordered_set<string>& wordDict, int startIdx){
vector<string> res; for (int i = ; i < s.size(); i++) {
string leftS = s.substr(, i); unordered_set<string>::iterator us_iter = wordDict.find(leftS); if (us_iter != wordDict.end()) { int rightRLIdx = i + startIdx; vector<string> rightV;
if (idx_words.find(rightRLIdx) != idx_words.end()){
rightV = idx_words[rightRLIdx];
}else{ string rightS = s.substr(i, s.size() - i); rightV = match(rightS, wordDict, rightRLIdx);
idx_words[rightRLIdx] = rightV;
} for (int ii = ; ii < rightV.size(); ii++) {
string tmpS = leftS + " " + rightV[ii]; res.push_back(tmpS);
}
}
} if (wordDict.find(s) != wordDict.end()) {
res.push_back(s);
} return res;
} vector<string> wordBreak(string s, unordered_set<string>& wordDict) {
vector<string> res; res = match(s, wordDict, ); return res;
}