/*给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-palindromic-substring
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。*/
本文采用动态规划
分奇数偶数。状态转移方程如下:
i==j的时候F[i][j]=1;
i<j的时候F[i][j]=F[i-1][j-1]+2(if(两边的字母相等));
画一个表格可以更方便理解。复习时看算法习题集。
#include<iostream>
#include<string>
using namespace std;
string str = { "iptmykvjanwiihepqhzupneckpzomgvzmyoybzfynybpfybngttozprjbupciuinpzryritfmyxyppxigitnemanreexcpwscvcwddnfjswgprabdggbgcillisyoskdodzlpbltefiz" };
int F[1100][1100] = { 0 };
void build() {
for (int i = 0; i < str.length(); i++) { //空串为1,一个字符串为1
F[i][i] = 1;
if (i + 1 < 1010) {
if ( str[i] == str[i + 1])F[i][i + 1] = 2;
else F[i][i + 1] = 0;
}
}
}
void Print() {
for (int i = 0; i < str.length(); i++) {
for (int j = 0; j <= i; j++) {
cout << F[j][i];
}
cout << endl;
}
}
int main() {
void Print();
if (str.empty() == 1) cout << NULL;
else { //可以画一个表格,先填对角线。从对角线向上填。即间隔为r(间隔为
//1的时候,初始化为1
//的时候不断被的向上填表。填到最后找最大值即可。
build();
for (int r = 2; r <= str.length() - 1; r++) {
for (int i = 0; i < str.length() - r + 1; i++) {
int j = r + i;
if (str[i] == str[j] && F[i + 1][j - 1] != 0) F[i][j] = F[i + 1][j - 1] + 2;
else F[i][j] = 0;
}
}
// Print();
int t = -1, x, y;
for (int i = 0; i < str.length(); i++) {
for (int j = 0; j <= i; j++) {
if (F[j][i] > t) {
t = F[j][i];
x = i; y = j;
}
}
}
cout << t;
if (y > x) {
for (int i = x; i <= y; i++) {
cout << str[i];
}
}
else if (x == y) {
cout << str[0];
}
else if (y < x) {
for (int i = y; i <= x; i++) {
cout << str[i];
}
}
}