PTA——L2-008 最长对称子串(最长回文字串问题)

本文介绍了两种方法寻找给定字符串中的最长对称子串:暴力两边扩展O(n^2)和Manachers算法O(n)。详细展示了如何使用Manachers算法求解,以字符串IsPAT&TAPsymmetric?为例,输出最长对称子串长度11。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、题目

L2-008 最长对称子串
分数 25

全屏浏览

切换布局
作者 陈越
单位 浙江大学
对给定的字符串,本题要求你输出最长对称子串的长度。例如,给定Is PAT&TAP symmetric?,最长对称子串为s PAT&TAP s,于是你应该输出11。

输入格式:
输入在一行中给出长度不超过1000的非空字符串。

输出格式:
在一行中输出最长对称子串的长度。

二、题解

法一:暴力两边扩展(O(n^2))

  • 求回文字子串,首先我们可以将原字符串用原字符串不存在的字符隔开,这样就变成了奇数串!
  • 我们可以枚举每一个字符,以该字符为中心向两边扩展,扩展的最大步数,即为最长回文子串的长度!
  • 时间复杂度O(n^2),数据范围只有1e3,可以过
#include<bits/stdc++.h>
using namespace std;

#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define fi first
#define se second
const int N = 1e5+10, INF = 0x3f3f3f3f;

void solve() {
	int ans=0,cnt=0;
	string a;
	getline(cin,a);
	char s[N];
	int len=a.size();
	s[++cnt]='#';
	for(int i=0;i<len;i++) //将每个字符隔开,变为奇数串 
	  s[++cnt]=a[i],s[++cnt]='#';
//	printf("%s\n",s+1);
	for(int i=1;i<=cnt;i++){
		int l=i-1,r=i+1,sum=0;
		while(l>0&&r<=cnt&&s[l]==s[r]) //向两边扩展 
		  l--,r++,sum++;
		ans=max(ans,sum); //取较大值 
	}
	cout<<ans;
}

signed main() {
//	IOS;
	int T=1;  
//	cin>>T;
	while(T--) {
		solve();
	}
	return 0;    
}
/*
Is PAT&TAP symmetric?

11
*/

法二:manacher(O(n))

  • 第二种方法就是马拉车算法了,可以线性的求出最长回文子串的长度!
  • 该算法的核心就是充分利用之前已求出的回文串,来计算当前的回文串。
#include<bits/stdc++.h>
using namespace std;

#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define fi first
#define se second
const int N = 1e5+10, INF = 0x3f3f3f3f;
int p[N]; //回文半径 

void solve() {
	int ans=0,cnt=0;
	string a;
	getline(cin,a);
	char s[N];
	int len=a.size();
	s[++cnt]='#';
	for(int i=0;i<len;i++) //将每个字符隔开,变为奇数串 
	  s[++cnt]=a[i],s[++cnt]='#';
	int M=0,R=0; //对称点M,区间右端点R 
	for(int i=1;i<=cnt;i++){ 
		if(i<=R) p[i]=min(p[2*M-i],R-i+1); //在区间内 
		while(i-p[i]>0&&i+p[i]<=cnt&&s[i-p[i]]==s[i+p[i]])
		  ++p[i]; //暴力扩展  
		if(i+p[i]-1>R) //更新区间 
		  M=i,R=i+p[i]-1;
	} 
	for(int i=1;i<=cnt;i++)
	  ans=max(ans,p[i]);
	cout<<ans-1;
}

signed main() {
//	IOS;
	int T=1;  
//	cin>>T;
	while(T--) {
		solve();
	}
	return 0;    
}
/*
Is PAT&TAP symmetric?

11
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值