回文串

题目描述

现在给你一个字符串S,请你计算S中有多少连续子串是回文串。 

输入

输入包含多组测试数据。每组输入是一个非空字符串,长度不超过5000.

输出

对于每组输入,输出回文子串的个数。

样例输入

aba

 

 

样例输出

4

分析:

       如果暴力的话,TLE应该是没跑的。为了降低时间复杂度,我们可以用空间换时间,把一维展开成二维。我们假设字符串存储在下标为0到n - 1的数组中,其中每一个字符串我们可以表示为Sij(0 <= i <= j <= n - 1),这样我们可以用二维数组的一半来存储各个字符串。然后判断每个字符串是否为回文串,遍历一下就好了。

      如何判断呢?当字符串长度大于等于3的时候,我们开辟上面所说的一个二维数组judge,judge[i][j]表示Sij是否为回文串。它的子问题就是如果S[i] == S[j],那么judge[i + 1][j - 1]是否为回文串。可以想到,我们用分治的方法自底向上计算,从而判断所有的字符串。

#include<bits/stdc++.h>

using namespace std;

const int N = 5010;
char a[N];
bool judge[N][N];

int main(){
	while(~scanf("%s", a)){
		int n = strlen(a);
		int res = 0;
		for(int i = n - 1; i >= 0; i--){
			for(int j = i; j < n; j++){
				judge[i][j] = (judge[i + 1][j - 1] || j - i < 3) && a[i] == a[j];
				if(judge[i][j]) res++;
			}
		}
		printf("%d\n", res);
		memset(a, '\0', sizeof(a));
		memset(dp, 0, sizeof(judge));
	}
	return 0;
} 

 

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值