Word Break
Given a string s and a dictionary of words dict, determine if s 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"
.
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"]
.
思路:
思路很简单,首先考察字典里的单词的长度,据此截取字符串前端的子串与字典进行比较。如果符合,就从此处截断,继续考察后面字符串即可。
第一题有一个比较恶心的例子,也就是一个有很长的"aaaaaaaa"后面跟着一个“b",偏偏字典里是{"a", "aa", "aaa", "aaaa"}。如果从前分割字符串就会超时,倒是从后面分割就可以迅速发现这个问题。
第二题是第一题的变种,无非是从找到一个解即结束改为搜索整个解空间而已。
题解:
class Solution {
public:
int min_word_length;
int max_word_length;
bool testWordBreak(const string& s, const unordered_set<string>& dict)
{
const int LEN_S = s.size();
if (s.size() == 0 || dict.find(s) != dict.end())
return true; // already part of the dict
for(int i = min_word_length; i <= min(max_word_length, LEN_S); ++i)
if (dict.find(s.substr(LEN_S - i)) != dict.end() &&
testWordBreak(s.substr(0, LEN_S - i), dict))
return true;
// cannot make a match
return false;
}
bool wordBreak(string s, unordered_set<string> &dict) {
max_word_length = 0;
min_word_length = 99999; // very large integer
for(auto& d : dict)
max_word_length = max(max_word_length, int(d.size())),
min_word_length = min(min_word_length, int(d.size()));
return testWordBreak(s, dict);
}
};
class Solution {
public:
int max_word_length;
int min_word_length;
vector<string> current_breaks;
vector<string> generated_sentence;
void generate_sentence()
{
string s = current_breaks.back();
for(int i = int(current_breaks.size()) - 2; i >= 0; --i)
s += string(" ") + current_breaks[i];
generated_sentence.push_back(s);
}
void testWordBreak(const string& s, const unordered_set<string>& dict)
{
const int LEN_S = s.size();
if (LEN_S == 0)
{
generate_sentence();
return;
}
for(int i = min_word_length; i <= min(max_word_length, LEN_S); ++i)
{
string substr = s.substr(LEN_S - i);
if (dict.find(substr) != dict.end())
{
current_breaks.push_back(substr);
testWordBreak(s.substr(0, LEN_S - i), dict);
current_breaks.pop_back();
}
}
}
vector<string> wordBreak(string s, unordered_set<string> &dict) {
generated_sentence.clear();
max_word_length = 0;
min_word_length = 99999; // very large integer
for(auto& d : dict)
max_word_length = max(max_word_length, int(d.size())),
min_word_length = min(min_word_length, int(d.size()));
testWordBreak(s, dict);
return generated_sentence;
}
};