5. Longest Palindromic Substring
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example 1:
Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
Example 2:
Input: "cbbd" Output: "bb"
问题分析:采用暴力算法可以找出所有字符串的组合,再看是不是回文,然而很多都是重复计算。比如我们已知cb不是回文的情况下,再计算cbb是没有意义的。同理,已知bd不是回文的情况下,计算bbd。
所以dp[i][j]=dp[i+1][j-1]&&s[i]==s[j] 即i+1~ j-1是回文,且s[i]和s[j]相等。
因此我们可以构造一个二维数组,来做标记。如果为true,表示i~j是回文字符串,并且我们只关心dp标志矩阵的上半部分即可。
在标志过程中,首先直接构造出对角线及其上一条对角线的元素。然后再根据长度和首位置去求其他位置。
#include<iostream>
#include<string>
#include<stdint.h>
using namespace std;
class Solution {
public:
string longestPalindrome(string s) {
if (s.size() == 0)
return "";
int sSize = s.size();
//首先对斜对角以及及其上一对角线赋值
//定义标记数组
//bool dp[sSize][sSize] = { false };
bool **dp = new bool*[sSize];
for (int i = 0; i < sSize; i++)
{
dp[i] = new bool[sSize];
memset(dp[i], 0, sSize*sizeof(bool));
}
for (int i = 0; i<sSize; i++)
{
dp[i][i] = true;
if (i + 1<sSize && (s[i] == s[i + 1]))
dp[i][i + 1] = true;
}
//从每行第三个对角线上开始
for (int k = 3; k<=sSize; k++) //k代表字符长度
{
for (int i = 0; i + k - 1<sSize; i++)//首元素
{
int j = i + k - 1;
dp[i][j] = dp[i + 1][j - 1] && (s[i] == s[j]);
}
}
//根据dp去找最长字符
string re = "";
int maxlength = INT32_MIN;
for (int i = 0; i<sSize; i++)
{
for (int j = 0; j<sSize; j++)
{
if ((dp[i][j] == true) && (j - i + 1>maxlength))
{
maxlength = j - i + 1;
re = s.substr(i, maxlength);
}
}
}
for (int i = 0; i<sSize; i++) {
delete[] dp[i];
}
delete[] dp;
return re;
}
};