算法笔记-回文篇

文章讲述了如何利用递归和滑动窗口的方法解决LeetCode中的回文子串问题,包括判断单个字符、双字符和多字符回文串,以及计算最长回文子串的算法实现。
摘要由CSDN通过智能技术生成

2024-1-9

判断是否为回文子串:算法思想递归

核心思想

若串s为"abcba",i指向第一个字符a,j指向最后一个字符a,已知"bcb"为回文串,若s[i]==s[j],则串s为回文子串。

代码

bool fun(char *p,int i,int j) {//判断是否为回文串
	if (i==j)//个数为一个
		return true;
	else if (p[i] == p[j] && i+1==j)return true;
	else if (p[i] == p[j] && fun(p,i+1,j-1))return true;
	return false;
}

leetcode 647题 回文子串

题目

给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。

核心思想:滑动窗口

将子串是否为回文子串存储在bool类型二维数组a中,例如在“abcba”中,a[1][3]==true代表子串“bcb”为回文子串,按照上一算法思想(已知"bcb"为回文串,若s[i]==s[j],则串s为回文子串),即: a[i+1][j-1]==true && s[i]==s[j] ,则a[i][j]==true .

对于长度为1或2的子串,可以直接判断。

if (i == j || i + 1 == j) {
    if (s[i] == s[j]){
	    num++;
		a[i][j] = true;
	}
	else
		a[i][j] = false;
}

循环如图所示。

代码

int CountStr(char* s) {//统计字符串大小
	int i = 0;
	while (*s != '\0') {
		i++;
		s++;
	}
	return i;
}
int countSubstrings(char* s) {//统计回文子串数量
	bool a[1000][1000] = {};
	int num=0;
	int strSize = CountStr(s);
	for (int j = 0; j < strSize; j++) {
		for (int i=0;i<=j;i++) {//上三角两层循环
			if (i == j || i + 1 == j) {//初始状态
				if (s[i] == s[j]){
					num++;
					a[i][j] = true;
				}
				else
					a[i][j] = false;
			}
			else//由初始状态向左上角推
				if (s[i] != s[j])
					a[i][j] = false;
				else if (a[i + 1][j - 1]){
					a[i][j] = true; 
					num++;
				}
				else
					a[i][j] = false;
		}
	}
	return num;
}

leetcode 5题 最长回文子串 

题目

给你一个字符串 s,找到 s 中最长的回文子串。

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

按照647题的思路可以遍历所有回文子串,因此只要在发现回文子串时记录子串的长度nowsize,然后在每轮循环的时候记录更新最大回文子串长度maxsize,然后记录该子串的起始位置maxi即可。

if (nowsize > maxsize) {
    maxsize = nowsize;
    maxi = j - nowsize + 1;
}

 题目最后要求return字符串,代码如下。

char* returnStr = (char*)malloc(sizeof(char) * maxsize + 1);
returnStr[maxsize] = '\0';
strncpy(returnStr, s+ maxi, maxsize);
return returnStr;
int CountStr(char* s) {
	int i = 0;
	while (*s != '\0') {
		i++;
		s++;
	}
	return i;
}
char* longestPalindrome(char* s){
    if (*s =='\0') {
            return "";
        }
	bool a[1000][1000] = {};
	int maxsize = 0,nowsize=0,maxi=0;
	int strSize = CountStr(s);
	for (int j = 0; j < strSize; j++) {
		for (int i = 0; i <= j; i++) {
            if(j - i + 1>maxsize){
                if (i == j || i + 1 == j) {
                    if (s[i] == s[j]) {
                        a[i][j] = true;
                        nowsize = j - i + 1;
                    }
                    else
                        a[i][j] = false;
                }
                else
                    if (s[i] != s[j])
                        a[i][j] = false;
                    else if (a[i + 1][j - 1]) {
                        a[i][j] = true;
                        nowsize = j - i + 1;
                    }
                    else
                        a[i][j] = false;
                if (nowsize > maxsize) {
                    maxsize = nowsize;
                    maxi = j - nowsize + 1;
                }
            }
		}
	}
	char* returnStr = (char*)malloc(sizeof(char) * maxsize + 1);
	returnStr[maxsize] = '\0';
	strncpy(returnStr, s+ maxi, maxsize);
	return returnStr;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值