Given a string s and a dictionary of words dict, determine ifs can be segmented into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode",
dict = ["leet", "code"].
Return true because "leetcode" can be segmented as "leet code".
I made a mistake about backtracking the string. My first version was as follows:
bool wordBreak(string s, int pos, unordered_set<string>& wordDict) {
if(pos >= s.size()) {return true;}
for(int i = pos + 1; i <= s.size(); ++i) {
string tmp = s.substr(pos, i - pos);
if(wordDict.find(tmp) != wordDict.end()) {
wordBreak(s, i, wordDict);
}
}
}Actually this is not correct. Suppose the wordDict is "leet" "code". The string s : leetcode.
the first loop will match, leet; then pushed onto stack. The recursion for will go to "code". This should return true. But since this is recursion, it will go back to the first loop again, then return false. String recursion should set a flag. Once the flag
went to true, it should always just return without changing the flag anymore.
The time complexity is pow(2, n). T = T(n-1) + T(n-2) ... + 1
#include <string>
#include <unordered_set>
#include <iostream>
#include <vector>
using namespace std;
//Recursion
void wordBreak(string s, int pos, unordered_set<string>& wordDict, bool& found) {
if(found) return;
if(pos >= s.size()) {found = true; return;}
for(int i = pos + 1; i <= s.size(); ++i) {
string tmp = s.substr(pos, i - pos);
if(wordDict.find(tmp) != wordDict.end()) {
wordBreak(s, i, wordDict, found);
}
}
}
// DP method
bool wordBreakII(string s, unordered_set<string>& wordDict) {
if(s.size() == 0) return true;
vector<int> dp(s.size(), 0);
for(int i = 0; i < s.size(); ++i) {
for(int j = 0; j <= i; ++j) {
if((!j || dp[j-1]) && (wordDict.find(s.substr(j, i - j + 1)) != wordDict.end())) {
dp[i] = 1;
break;
}
}
}
return dp[s.size() - 1];
}
bool wordBreak(string s, unordered_set<string>& wordDict) {
int pos = 0;
bool found = false;
wordBreak(s, pos, wordDict, found);
if(found) return true;
}
int main(void) {
unordered_set<string> wordDict;
wordDict.insert("aaaa");
wordDict.insert("aaa");
cout << wordBreakII("aaaaaaa", wordDict) << endl;
}
~

本文探讨了如何判断一个字符串是否能被分割成一个或多个字典中出现的单词的问题,并提供了两种解决方案:递归回溯法与动态规划法。通过具体实例说明了递归回溯时可能遇到的问题及解决方法,最后给出了动态规划实现的代码示例。
1597

被折叠的 条评论
为什么被折叠?



