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"
.
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; } };