5. Longest Palindromic Substring
-
题目描述
-
题目思路1
这道题LeetCode上的标签是Dynamic programming,即动态规划,第一个思路就是用动态规划来解。
首先维护一个二维数组dp[j][i]。这个动态数组表示[j, i]之间是否有回文。当j = i时,只有一个字符,肯定是回文,当 j + 1 = i 时,说明是相邻的字符,那么需要比较s[j]和s[i]是否相等,如果i - j >= 2时,除了判断s[i]和s[j]之外,还必须判断dp[j+1][i-1]是否为真,如果为真,就是回文串。
以babad为例
当i = 4,j = 0时,i - j > 2,首先要判断s[i] 和s[j]是否相等,其次,还要判断j和i之间的a b a 是否为回文串,如何判断a b a 是否为回文串,就是要看dp[][]数组,看dp数组的[j+1][i-1]是否为真。
- C++实现
class Solution
{
public:
string longestPalindrome(string s)
{
int len = 1; //存储当前的回文长度
int left = 0; //回文长度的起始位置
int n = s.length();
int **dp;
dp = new int *[n];
for (int i = 0;i < n;i++)
{
dp[i] = new int[n];
}
for (int i = 0;i < n;i++)
{
dp[i][i] = 1;
for (int j = 0;j < i;j++)
{
dp[j][i] = (s[i] == s[j] && (i - j < 2 || dp[j+1][i-1]));
if (dp[j][i] && len < i - j + 1)
{
len = i - j + 1;
left = j;
}
}
}
return s.substr(left,len);
}
};
用C++实现的效率太慢了,参考LeetCode给出的数据
-
第二次刷
-
递归写法
判断字符串
str
是否是回文串
class Solution {
public:
bool is(string s,int i,int j)
{
if(j-i==0)
return true;
if(j-i==1)
{
if(s[i]==s[j])
return true;
else
return false;
}
if(s[i]==s[j] && is(s,i+1,j-1))
return true;
else
return false;
}
string longestPalindrome(string s) {
int len=s.length();
string temp;
string result;
int max=0;
for(int i=0;i<len;i++)
{
for(int j=i;j<len;j++)
{
if(is(s,i,j))
{
if(max<j-i+1)
{
result.replace(0,result.length(),s.substr(i,j-i+1));
max=j-i+1;
}
}
}
}
return result;
}
};
- 由动态规划改为递归写法
class Solution
{
public:
string longestPalindrome(string s)
{
int length = s.length();
int strmax = 0;
int left = 0;
int right = 0;
vector<vector<bool>> dp(length, vector<bool>(length));
for (int i = 0; i < length; i++)
{
for (int j = 0; j < length; j++)
{
dp[i][j] = true;
}
}
for (int i = 0; i < length - 1; i++)
{
dp[i][i + 1] = (s[i] == s[i + 1]);
}
//填充dp数组中其他空余的部分
for (int i = length - 3; i >= 0; i--)
{
for (int j = length - 1; j >= i + 2; j--)
{
dp[i][j] = (s[i] == s[j] && dp[i + 1][j - 1]);
}
}
//检查dp数组中为true的部分 并且找出最大值
for (int i = 0; i < length; i++)
{
for (int j = i; j < length; j++)
{
if (dp[i][j])
{
if (strmax < j - i + 1)
{
left = i;
right = j;
strmax = j - i + 1;
}
}
}
}
return s.substr(left, right - left + 1);
}
};
从运行结果来看,即便是这个DP版本的程序,也有很多可以改进的地方。
-
参考资料
-
参考资料:
1 《Leetcode-5-Longest Palindromic Substring》 http://zyy1217.com/2017/04/09/leetcode5/