一、问题描述
Given a string s, find the longest palindromic substring(最长回文字符串) in s. You may assume that the maximum length of s is 1000.
Example:
Input: “babad”
Output: “bab”
Note: “aba” is also a valid answer.
Example:
Input: “cbbd”
Output: “bb”
二、动态规划算法DP
总体思想:要想知道长度为len的子串是否是回文,就要知道长度为len-2子串(len串的掐头去尾)是否为回文。而len-2子串可以通过前面计算保存判断结果查询即可(temp[i][j])。
创建布尔类型二维数组temp[i][j] ,记录保存从i 到 j 的字串,是否是回文串,如果为回文串则为True,否则为False。
第一轮:单个字符自己是回文。即temp[i][i]=true。
- 第二轮:判断相邻元素是否相同,如果相同则设置temp[i][i+1]=true,否则为false。
- 第三轮:二重循环,判断当距离大于2,即从3开始,进行遍历,逐渐增大距离。(1)如果s[i] == s[j] 那么是否是回文决定于 temp[i+1][ j - 1]。
(2)当 s[i] != s[j] 的时候, temp[i][j] 直接就是 false。
同时记录起始位置、结束位置、最长距离。 - 算法性能:二维动态规划,Time:O(n^2), Space:O(n^2)
- 下图能够方便理解。当i>j时,不成立,所以不在考虑范围。
源自博客http://blog.csdn.net/kang_tju/article/details/53907446
- 感谢博客作者分享,供参考。
http://blog.csdn.net/hopeztm/article/details/7932245
三、程序示例
C#版本
class Program
{
//动态规划算法,解决最长回文串问题
public static string LongestPalindrome(string s)
{
if (s==null || s.Length==0)
{
return null;
}
bool[,] temp = new Boolean [s.Length, s.Length];
//第一轮:[i,i]复制
for (int i = 0; i < s.Length; i++)
{
temp[i, i] = true;
}
//第二轮:[i,i+1]
int maxLen = 1;
int begin = 0;
int end = 0;
for (int i = 0; i < s.Length-1; i++)
{
if (s[i] == s[i+1])
{
temp[i, i + 1] = true;
maxLen = 2;
begin = i;
end = i + 1;
}
}
//第三轮:三重循环
for (int len = 2; len < s.Length; len++)
{
for (int i = 0; i + len < s.Length; i++)
{
int j = i + len;
if (s[i] != s[j])
{
temp[i, j] = false;
}
else
{
if (temp[i+1,j-1])
{
temp[i, j] = true;
if (len + 1 > maxLen)
{
maxLen = len + 1;
begin = i;
end = j;
}
}
else
{
temp[i, j] = false;
}
}
}
}
return s.Substring(begin, end-begin+1);
}
static void Main(string[] args)
{
//string str = "abaaba";
//string str = "eabcb";
string str = "cbbd";
string result = LongestPalindrome(str);
}
}