回文字符串

回文字符串

像"aavbvaa"这样正着反着读都一样的字符串就是回文字符串

单个字符串

判断方法一

从字符串的两端进行比对,相同i++,j–,直到到达i>=j

bool check(string s){
	int i,j=s.size()-1;
	for(i=0;i<str.length()/2;i++,j--) 
        if(str[i]!=str[j]) break;   //如果有一个不相匹配就结束循环
	if(i>=j) return 1;
	return 0;
}

判断方法二

无需采用指针,因为计算机除法向下取整的缘故,奇数长度的字符串的中位数无需判断

bool check(string s){
    int len=s.size()-1;
    for(int i=0;i<=len/2;i++){
        if(s[i]!=s[len-i]) return 0;
    }
    return 1;
}
字符串区间

给出一个字符串。判断其任意长度的子串是否为回文串,下面默认字符串区间为[1,len]

暴力

实际上以字符串的某个字符为中心,使用双指针向两边扩散,但是要分为三种情况具体讨论

  • 回文串长度为奇数,那么该字符为中位数,初始指针分别为该元素下标的前一个和后一个
  • 回文串长度为偶数,且该字符作为中心线偏左的元素,初始指针分别为该元素下标本身和后一个
  • 回文串长度为偶数,且该字符作为中心线偏右的元素,初始指针分别为该元素下标本身和前一个
bool vis[maxn][maxn];
char s[maxn];

for(int i=1;i<=n;i++){
	vis[i][i]=1;
	int l=i-1,r=i+1;
	while(l>=1 && r<=n && s[l]==s[r]){
		vis[l][r]=1;
		l--,r++;
	}
	l=i,r=i+1;
	while(l>=1 && r<=n && s[l]==s[r]){
		vis[l][r]=1;
		l--,r++;
	}
	l=i-1,r=i;
	while(l>=1 && r<=n && s[l]==s[r]){
		vis[l][r]=1;
		l--,r++;
	}
}

dp

设dp(i,j),i<=j代表区间[i,j]的子串为回文串

考虑双重循环,第一层枚举字符串所有字符,第二层枚举它前面的所有字符,那么显然这里存在一个递推关系

  • 当s[i]==s[j]且i-j>1且dp(j+1,i-1)==1时,显然dp(j,i)=1

  • 当s[i]==s[j]且i-j<=1时,dp(j,i)=1

bool dp[maxn][maxn];
char s[maxn];

for(int i=1;i<=n;i++){
	dp[i][i]=1;
	for(int j=1;j<i;j++)
		if(s[i]==s[j]){
			if(i-j<=1) dp[j][i]=1;
			else if(dp[j+1][i-1])
				dp[j][i]=1;
		}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值