每天一道LeetCode-----将字符串切分成若干单词,使得每个单词都在给定的字典中,求出所有的切分结果
2018-01-29 14:42
525 查看
Word Break
原题链接Word Break给定一个字符串和单词字典,将字符串切分成若干个单词,使每个单词都在字典中。判断是否可以成功切分
假设字符串s[0 : n-1]可以成功切分成若干个单词,那么一定存在一个i使得s[0 : i-1]可以成功切分成若干个单词,同时s[i : n-1]在字典中存在,可以采用动态规划的思想求解
令dp[i]表示s[0 : i-1]是否可以成功切分成若干单词组合,最终要求解的是dp
。
那么每求一个dp[i]使,就在i前面寻找是否存在一个j使得dp[j]为真且s[j : i-1]在字典中
代码如下
class Solution { public: bool wordBreak(string s, vector<string>& wordDict) { unordered_set<string> hash; size_t maxLen = 0; for(auto& word : wordDict) { hash.insert(word); maxLen = std::max(maxLen, word.size()); } vector<int> dp(s.size() + 1, 0); dp[0] = 1; for(int i = 1; i <= s.size(); ++i) { for(int j = i - 1; j >= 0 && (i - j) <= maxLen; --j) { /* 寻找一个j使得s[0 : j-1]可以拆分 */ if(dp[j]) { /* 判断s[j : i-1]是否在字典中 */ string word = s.substr(j, i - j); if(hash.find(word) != hash.end()) { /* 标记s[0 : i-1]可以成功拆分 */ dp[i] = 1; break; } } } } return dp[s.size()]; } };
Word Break II
原题链接Word Break II寻找所有的拆分结果
还是采用上述的思路,要将s[0 : n-1]拆分,那么就从后向前寻找i使得s[i : n-1]在字典中,然后拆分s[0 : i-1],将结果进行组合
代码如下
class Solution { public: vector<string> wordBreak(string s, vector<string>& wordDict) { unordered_set<string> hash; for(auto& word : wordDict) hash.insert(word); return breakWord(s, hash); } private: vector<string> breakWord(string& s, unordered_set<string>& hash) { /* 防止重复计算 */ if(m.find(s) != m.end()) return m[s]; vector<string> res; for(int i = s.size() - 1; i >= 0; --i) { string word = s.substr(i); if(hash.find(word) != hash.end()) { string str = s.substr(0, i); vector<string> prevWords = breakWord(str, hash); for(auto& words : prevWords) res.emplace_back(words + " " + word); if(i == 0) res.emplace_back(word); } } m[s] = res; return res; } private: unordered_map<string, vector<string>> m; };
相关文章推荐
- 每天一道LeetCode-----将字符串切分,使每个子串都是回文串,计算所有可能结果和最小切分次数
- 每天一道LeetCode-----以单词为单位逆序字符串,每个单词之间以一个空格分隔(原字符串中可能有多个空格)
- 每天一道LeetCode-----比较两个字符串,每个字符串被若干'.'分成多个数字,一个个比较
- 每天一道LeetCode-----计算给定范围内所有数的与运算结果
- 给定一个只包含小写字母的字符串,删除重复的字母,每个字母只出现一次。在所有结果中,输出字典顺序最小的。
- 阿里校招笔试——给定一个字符串S和有效单词的字典D,请确定可以插入到S中的最小空格数,使得最终的字符串完全由D中的有效单词组成,并输出解。
- 每天一道LeetCode-----在字符串s中找到最短的包含字符串t中所有字符的子串,子串中字符顺序无要求且可以有其他字符
- 每天一道LeetCode-----寻找给定字符串中重复出现的子串
- 每天一道LeetCode-----找到1,2,...,n这n个数所有的组合,每个组合有k个元素,且元素大小递增
- 每天一道LeetCode-----给定序列中2/3/4个元素的和为target的所有集合,或3个元素的和最接近target的集合
- 每天一道LeetCode----从数组中选择若干不连续元素使得总和最大
- 给定一个字符串s和一个单词dict的字典,确定s是否可以分割成一个或多个字典单词的空格分隔的序列。 s ="leetcode", dict =["leet", "code"].
- 给定一个字符串s和一个单词dict的字典,在s中添加空格来构造一个句子,其中每个单词都是有效的字典单词。
- 每天一道LeetCode-----找到二叉树所有和为给定值的路径
- 每天一道LeetCode-----找出给定序列的所有子序列
- 每天一道LeetCode-----以字符串的形式输出二叉树所有从根节点到叶子节点的路径
- 每天一道LeetCode-----找到给定序列中所有和为某个值的集合或集合个数,序列中可以有/无重复项,集合元素顺序不同算不同集合等
- 每天一道LeetCode-----给定字符串s和字符数组words,在s中找到words出现的位置,words内部字符串顺序无要求
- 给定两个字符串和一个字典,从头到尾找到最短变换序列的长度,使得:一次只能改变一个字符每个中间词必须存在于字典中
- 每天一道LeetCode-----给定一个矩阵,如果某个元素是0,就将所在行所在列上所有元素否置0