这两题主要考察动态规划问题, 由于对此类问题不是很熟悉,参考一些资料以及算法
动态规划问题:将一个较为棘手的大问题转换为一些小问题并对这些小问题进行求解,且局部最优解有可能是全局最优解,该方法保存了中间结果,避免了多次重复计算一些中间值。
感谢博客http://www.cnblogs.com/TenosDoIt/p/3385644.html 其代码通俗易懂
代码如下
Word Break
bool wordBreak(string s, unordered_set<string> &dict)
{
vector<bool> flag(s.size, false);
for(int i = 1; i <= s.size(); ++i)
{
if((flag[i-1]==false)&&(dict.find(s.substr(0,i))!=dict.end()))
flag[i-1] = true;
//前缀满足划分后,具体分析后缀
if(flag[i-1])
{
if(i==s.size)
return true;
//注意下标的意义
for(int j = 1; j <= s.size()-i; ++j)
{
if(flag[j+i-1]==false&&dict.find(s.substr(i,j))!=dict.end())
flag[j+i-1]=true;
if(j==s.size()-i && flag[j+i-1] == true)
return true;
}
}
}
return false;
}
Word Break ||
代码
class Solution
{ public:
vector<string> wordBreak(string s, unordered_set<string> &dict)
{
int len = s.size();
vector<bool> flag(len, false);
vector<string> result;
bool ** pre = new bool *[len];
for(int i = 0; i < len; ++i)
{
pre[i] = new bool[len];
memset(pre[i], 0, len);
}
for(int i = 1; i <= len; ++i)
{
if(dict.find(s.substr(0,i))!=dict.end())
{
flag[i-1] = true;
pre[i-1][0] = true;
}
if(flag[i-1] == true)
{
for(int j = 1; j <= len-i; ++j)
{
if(dict.find(s.substr(i, j))!=dict.end())
{
flag[j+i-1] = true;
pre[j+i-1][i] = true;
}
}
}
}
vector<int> insertPos;
getResult(s, pre, len, len-1, insertPos, result);
return result;
}
//根据得到的数据(pre[][]来划分字符串)
void getResult(string s, bool **pre, int len, int currentPos, vector<int>insertPos, vector<string> &result)
{
if(currentPos == -1)
{
result.push_back(insertBlank(s, insertPos));
return ;
}
for(int i = 0; i < len; ++i)
{
if(pre[currentPos][i])
{
insertPos.push_back(i);
getResult(s, pre, len, i-1, insertPos, result);
insertPos.pop_back();
}
}
}
//不同词之间插入空格
string insertBlank(string s, vector<int>pos)
{
string result = "";
int base = 0;
for(int i = pos.size()-1; i>=0; --i)
{
if(pos[i] == 0) continue;
result += (s.substr(base,pos[i]-base) + " ");
base = pos[i];
}
result += s.substr(base, s.length()-base);
return result;
}
}