题目地址wordBreak
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”.
这道题用动态规划解:
动态规划的一般步骤为:
1.决定用存储什么历史信息以及用什么数据结构来存储信息
2.找到递推公式
3.如何从储存的历史信息中得到当前步的结果
4.考虑起始值。
对于这道题:
1.我们使用一个布尔数组来保存来保存历史信息,要保存的历史信息是以第i个字母结尾的字符串是否能用字典中的字符串表示,即bool res[];
2.找递推式,什么样的字符串能用字典中的字符串表示呢?首先,有没有一个包含第i个字母的子字符串可以在字典中找到,其次,除此那个包含第i个字母的字符串之外,字符串的剩余部分能否用字典表示,res[j] && zidian.count(str[j]),其中str[j]表示第j个可能的包含第i个字母的子字符串,res[j]表示之前保存的那个历史信息。
3.第2b步已经可以得到当前步的结果
4.起始值设为true,即一个空字符串我们认为包含在字典中。
代码如下:
bool wordBreak(string s, unordered_set<string> &dict)
{
bool *res = new bool[s.size() + 1];
res[0] = true;
for(int i = 1; i < s.size() + 1; ++i)
res[i] = 0;
for(int i = 0; i < s.size(); ++i)
{
for(int j = 0; j <= i; ++j)
{
if(res[j] && dict.count(s.substr(j, i - j + 1)))
{
res[i+1] = true;
break;
}
}
}
// for(int i = 0; i < s.size() + 1; ++i)
// cout << res[i] << " ";
// cout << endl;
return res[s.size()];
}