「题解」最长回文串

题目描述

给定一个字符串 s ,找到 s 中最长的回文子串,输出其长度。

你可以假设 s 的最大长度为 3000。

输入格式

第1行:1个字符串

样例

样例输入

babad

样例输出

3

分析

对于一个字符串s[l,r],他的最长回文字符串有如下两种情况
1.若s[l] == s[r] 且 s[l+1,r-1]为回文字符串,则s[l,r]会变为更长的一个回文字符串
2.否则在s[l,r-1]和s[l+1,r]之间必有一个最长的不超过r-l的回文字符串

凑字数的问题来了
如何才能判断s[l,r]为回文字符串呢?
大家当然可以循环搜索,用一个二维数组(清为-1)记录
初始值:Interval[i,i] (i=1~n)=1
当Interval[l+1,r-1]=-1,搜索;
当Interval[l+1,r-1]=1,返回值true,如果s[l]==s[r],那么Interval[l,r]=1;
当Interval[l+1,r-1]=0,返回值false,Interval[l,r]=0。
也可以用dp[l,r]是否等于l-r+1来O(1)判断(代码展示此方法)

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

const int M = 3e3 + 5;
char a[M];
int f[M][M];
int len;

void Read() {
	int temp = 0;
	char x = getchar();
	while(x != 10) {
		a[++ temp] = x;
		x = getchar();
	}
	len = temp;
}

int main() {
	Read();																	//读入
	memset(f, 0, sizeof f);
	for(int i = 1; i <= len; i ++) {
		f[i][i] = 1;
	}
	for(int i = 2; i <= len; i ++) {
		for(int l = 1; l <= len - i + 1; l ++) {
			int r = l + i - 1;
			if(a[l] == a[r] && f[l + 1][r - 1] == r - l - 1) {				//判断回文串
				f[l][r] = f[l + 1][r - 1] + 2;
			}
			else {
				f[l][r] = max(f[l][r - 1], f[l + 1][r]);
			}
		}
	}
	printf("%d", f[1][len]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yu_______chen/article/details/107449638