您的位置:首页 > 其它

【leetcode】Longest Palindromic Substring

2014-05-30 12:57 471 查看

题目:

给定个字符串,返回串中包含的最长的回文串。

分析:

所谓回文串就是将字符串翻转后与原字串串相同,如 ABA,翻转后仍为ABA。
我们考虑用dp来做,因为我们很容易就想到dp的状态转移方程。
状态方程:m[i, j]: 表示子串s[i]...s[j] 是否为回文,若是,令其为true,否则为false。
状态转移:m[i, j] = m[i + 1, j - 1] if s[ i ] == s[ j ]。也就是说s[ i ... j ] 中,当首尾相同时,s[i ... j ] 是否为为回文,要取决于m[ i + 1, j - 1] 是否为回文。
初始条件:m[i, i ] = true,这个好理解,一个字符的串就是回文串。但是,单单初始化对角线上的元素还不够(通过状态转移方程可以看出,不行的话自己画个m表,进行手写填表就很明了了),还要有m[i, i + 1] ,也就是主对角线右上的一层对角线信息。
结果:m表单纯的记录了是否为回文,这里要求的是返回最长的回文串,所以仅有m矩阵是不够的,还要我们定义额外的变量来记录结果。对于字符串而言,我们知道起始点,知道终止点 或者是起始点和长度,可以获得任意合法的子串,所以我们定义一个起始点变量start,长度变量longest。现在的问题是,start 和longest 要怎么样发生变化?什么时候发生变化呢?当然是当前的回文串长度大于已有回文串的长度的时候,当前回文串,也就是m[i,
j ] 为true的时候,这就是当前获得的回文串,那么我们比较它的长度与longest的大小,若比longest大,则更新longest和start 的值。

最终填写的表是一个方阵的上对角矩阵。



表中黑色的部分是初始化的信息,然后从start开始,从下向上,从左向右填写表。每次填一行,如图中红色紫色所示。
到这,问题就很明了了。

实现:

//参考代码
string longestPalindrome(string s) {
if(s.size() <= 1)
return s;
//vector<vector<bool> >dp(s.size(),vector<bool>(s.size(), false));
bool dp[1000][1000] = {false};
//bool **dp = new bool[s.size()][s.size()];
int Len = s.size();
int longest = 0;
int start = 0;
//init dp[i,i] = true
for (int i = 0; i < Len; ++i)
dp[i][i]  = true;
//init dp[i, i + 1]
for (int i = 0; i < Len - 1; ++i)
if(s[i] == s[i + 1])
{
dp[i][i + 1] = true;
longest = 2;
start = i;
}
for (int i = Len - 3; i >= 0; --i)
for(int j = i + 2; j < Len; ++j)
{
if(dp[i + 1][j - 1] && s[i] == s[j])
{
dp[i][j] = true;
if(longest < j - i + 1)
{
longest = j - i + 1;
start = i;
}
}
}
return s.substr(start,longest);
}


说明:开始的实现中用vector来表示动态表,结果一直超时,看来封装过的容器效率上就是不比原生的数组。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: