[LeetCode] [动态规划] Word Break
2014-03-21 20:57
288 查看
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 =
dict =
Return true because
问题描述:给定一个字符串s和一个由单词组成的字典dict,判断是否能够将s分段成一个或者多个字典中的单词。
对于s,可以有很多种进行分段的方式,如果在这些分段方式中至少有一种情况:被截断的各个部分都是dict中的单词,那么,s就能够分段成一个或者多个字典中的单词。因此,最简单的想法是,如果能够得到一个单词的所有分段形式,然后遍历这些分段序列,直到有一种分段情况下,所有的单词都是dict中的单词,那么,就返回true,没有找到,就返回false。当然,这种方法是不现实的。
为了判断,就必须进行分段。首先,将[beg, end)引用的字符串分成[beg, sep)和[sep, end),sep必须从beg+1一直到end,如果其中有一种情况,两个区间的字符串可以进行分段,那么[beg, end)就可以进行分段。然后就需要递归判断两个字符串是否可以进行分段。但是只能对[beg, sep)和[sep, end)中的一个使用递归的判断函数,因为,这样做复杂度太高,因此,只对[sep, end)使用递归的判断函数,对[beg, sep)使用dict来判断。于是有下面的代码:
提交的结果是:
TIme Limit Exceeded
超时了,说明算法的时间复杂度还是太高了,要设法进行优化。当进行递归时,如果分支中重复的分支很多,就可以使用动态规划。在判断[sep, end)时,使用了递归函数word,但是,如果对一个字符串进行考察可以知道,其中有很多重复判断,因此,必须减少重复判断,也就是增加记忆功能,将已经判断失败的字符串保存起来,当判断一个字符串时,可以先与失败的字符串比较,如果是失败的字符串,就继续下一轮判断,这样,可以加快判断。
For example, given
s =
"leetcode",
dict =
["leet", "code"].
Return true because
"leetcode"can be segmented as
"leet code".
问题描述:给定一个字符串s和一个由单词组成的字典dict,判断是否能够将s分段成一个或者多个字典中的单词。
对于s,可以有很多种进行分段的方式,如果在这些分段方式中至少有一种情况:被截断的各个部分都是dict中的单词,那么,s就能够分段成一个或者多个字典中的单词。因此,最简单的想法是,如果能够得到一个单词的所有分段形式,然后遍历这些分段序列,直到有一种分段情况下,所有的单词都是dict中的单词,那么,就返回true,没有找到,就返回false。当然,这种方法是不现实的。
为了判断,就必须进行分段。首先,将[beg, end)引用的字符串分成[beg, sep)和[sep, end),sep必须从beg+1一直到end,如果其中有一种情况,两个区间的字符串可以进行分段,那么[beg, end)就可以进行分段。然后就需要递归判断两个字符串是否可以进行分段。但是只能对[beg, sep)和[sep, end)中的一个使用递归的判断函数,因为,这样做复杂度太高,因此,只对[sep, end)使用递归的判断函数,对[beg, sep)使用dict来判断。于是有下面的代码:
bool word(string::iterator beg, string::iterator end, unordered_set<string> &dict) { if(beg == end) { return true; } if(dict.find(string(beg, end)) != dict.end()) { return true; } string::iterator sep = beg + 1; while(sep != end) { if(dict.find(string(beg, sep)) != dict.end() && word(sep, end, dict)) { return true; } ++sep; } return false; } bool wordBreak(string s, unordered_set<string> &dict) { if(s.empty()) return false; return word(s.begin(), s.end(), dict); }
提交的结果是:
TIme Limit Exceeded
超时了,说明算法的时间复杂度还是太高了,要设法进行优化。当进行递归时,如果分支中重复的分支很多,就可以使用动态规划。在判断[sep, end)时,使用了递归函数word,但是,如果对一个字符串进行考察可以知道,其中有很多重复判断,因此,必须减少重复判断,也就是增加记忆功能,将已经判断失败的字符串保存起来,当判断一个字符串时,可以先与失败的字符串比较,如果是失败的字符串,就继续下一轮判断,这样,可以加快判断。
class Solution { public: bool word(string::iterator beg, string::iterator end, unordered_set<string> &dict, set<string> ¬_seg) { if(beg == end) return true; if(dict.find(string(beg, end)) != dict.end()) { return true; } string::iterator sep = beg + 1; while(sep != end) { if(dict.find(string(beg, sep)) != dict.end() && dict.find(string(sep, end)) != dict.end()) { return true; } if(dict.find(string(beg, sep)) != dict.end()) { if(not_seg.find(string(sep, end)) == not_seg.end()) { if(word(sep, end, dict, not_seg)) { return true; } else { not_seg.insert(string(sep, end)); } } } ++sep; } not_seg.insert(string(beg, end)); return false; } bool wordBreak(string s, unordered_set<string> &dict) { if(s.empty()) return false; set<string> not_seg; return word(s.begin(), s.end(), dict, not_seg); } };
相关文章推荐
- 动态规划——Word Break 拆分词句【LeetCode】
- 【LeetCode】Word Break 动态规划
- 【LeetCode从零单排】No198.House Robber &&No91.Decode Ways&&139 word break(动态规划典型应用)
- leetcode做题总结,动态规划I(Triangle,Unique PathsI/II,Minimum Path Sum,Climbing Stairs,Jump Game,Word Break)
- 【LeetCode题解】动态规划:从新手到专家(一)
- leetcode 724. Find Pivot Index 左右边元素和相等 + 左边右边元素之和 + 动态规划DP
- 算法学习-动态规划-实战二(leetcode 85)
- [LeetCode]Delete and Earn题解(动态规划)
- [LeetCode] [动态规划] Triangle
- 【LeetCode从零单排】No.135Candy(双向动态规划)
- leetcode:Word Break
- Leetcode Solution – Word Break
- Leetcode题解 - 139. Word Break
- LeetCode 之 Word Break
- 【LeetCode-动态规划】Triangle
- [leetcode]climbing-stairs 动态规划 C++
- Leetcode(W9):123. Best Time to Buy and Sell Stock III(动态规划)
- LeetCode——Word Break
- [leetcode] 139 Word Break
- 【LeetCode】139. Word Break