520,我会处理回文数了,你会了么?(dp+中心扩散)

2023-11-04

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。

示例 2:

输入: “cbbd”
输出: “bb”

方法一:暴力匹配(Brute Force)

●根据回文子串的定义,枚举所有长度大于等于2的子串,依次判断它们是否是文;
●在具体实现时,可以只针对大于“当前得到的最长回文子串长度"的子串进行"回文验证”;
●在记录最长回文子串的时候,可以只记录“当前子串的起始位置”和“子串长度”,不必做截取。这一步我们放在后面的方法中实现。
说明:力解法时间复杂度高,但是思路清晰、编写简单。由于编写正确性的可能性很大,可以使用暴力匹配算法检验我们编写的其它算法是否正确。

java

	public static String longestPalindrome(String s) {
		int len = s.length();
		if (len < 2) {
			return s;
		}

		int maxLen = 1;
		int begin = 0;
		// 每次都会检查下标是否越界,因此先转化成 字符数组
		char[] charArray = s.toCharArray();
		// 枚举所有长度大于一的子串
		for (int i = 0; i < len - 1; i++) {
			for (int j = i + 1; j < len; j++) {
				if (j - i + 1 > maxLen && validPalindromic(charArray, i, j)) {
					maxLen = j - i + 1;
					begin = i;
				}
			}
		}
		return s.substring(begin, begin + maxLen);
	}

	/**
	 * 验证子串是否是回文子串
	 * 
	 * @param charArray
	 * @param left
	 * @param right
	 * @return
	 */
	private static boolean validPalindromic(char[] charArray, int left, int right) {
		while (left < right) {
			if (charArray[left] != charArray[right]) {
				return false;
			}
			left++;
			right--;
		}
		return true;
	}

python

class Solution:
    # 暴力匹配(超时)
    def longestPalindrome(self, s: str) -> str:
        # 特判
        size = len(s)
        if size < 2:
            return s

        max_len = 1
        res = s[0]

        # 枚举所有长度大于等于 2 的子串
        for i in range(size - 1):
            for j in range(i + 1, size):
                if j - i + 1 > max_len and self.__valid(s, i, j):
                    max_len = j - i + 1
                    res = s[i:j + 1]
        return res

    def __valid(self, s, left, right):
        # 验证子串 s[left, right] 是否为回文串
        while left < right:
            if s[left] != s[right]:
                return False
            left += 1
            right -= 1
        return True

方法二:动态规划

下面是「动态规划』问题的思考路径,供大家参考。
这道题比较烦人的是判断回文子串。因此需要一种能够快速判断原字符串的所有子串是否 是回文子串的方法,于是想到了[动态规划」。
「动态规划」的一个关键的步骤是想清楚「状态如何转移」。实际上回文天然具有「状态转移」性质。

●一个文去掉两头以后,剩下的部分依然是回文(这里暂不讨论边界情况) ; 依然从回文串的定义展开讨论:
●如果一个字符串的头尾两个字符都不相等,那么这个字符串一定不是回文串;
●如果一个字符串的头尾两个字符相等, 有必要继续判断下去。
。如果里面的子串是回文,整体就是回文串;
。如果里面的子串不是回文串,整体就不是文串。

即:在头尾字符相等的情况下,里面子串的回文性质据定了整个子串的回文性质,这就是状态转移。因此可以把「状态」定义为原字符串的一一个子串是否为回文子串。
第1步:定义状态
dp[i][j]|示子串s[i…j] 否为文子串,这里子串s[i… j]义为闭右闭区间,可以取到s[i] 和s[j]。
第2步:思考状态转移方程
在这一粉类讨论(根据头尾字符是否相等), 根据上面的分析得到:

dp[i][j] = (s[i] == s[j]) and dp[i + 1][j - 1]

说明: .

「动态规划」实上是在填一张二维表格,构成子串,因此i和j的关系是i <= j,因此,只需要填这张
表格对角线以上的部分。
看到dp[i + 1][j-1]就得考虑边界情况。
边界条件是:表达式[i + 1, j- 1]不构成区间,即长度严格小于2,即j-1-(i+1)+1<2,整理得j-i <3

这个结论很显然: j 一i < 3等价于j一i + 1< 4,即当子串s[i…j]的长等于2或者等于3的时候,实
只需要判断一下头尾两个字符是否相等就可以直接 下结论了。

●如果子串s[i + 1…j- 1]只有1个字符,即去掉两头,剩下中间部分只有1个字符,显然是文;
●如果子串s[i + 1…j-1]为空串,那么子串s[i, j]| -定是回文子串。

因此,在[s[i] == s[j]| 成立和j一i < 3的前提下,直接可以下结论,dp[i][j] = true,否则才执行状态转移。
第3步:考虑初始化
初始化的时候,单个字符一定回文串,因此把对角线先初始化为true, 即dp[i][i] = true
事实上,初始化的部分都可以省去。因为只有一个字符的时候一定文,dp[i][i] 根本不会被其它状态值所参考。
第4步:考虑输出
只要一得到dp[i][j] = true ,就记录子串的长度和起始位置,没有必要截取,这是因为截取字符串也要消耗性能,记录此时的回文子串的「起始位置」和回文长度」即可。
第5步:考虑优化空间
因为在填表的过程中,只参考了左下方的数值。实上可以优化,但是增加了代码编写和理解的难度
注意事项:总是先得到小子串的回文判定,然后大子串才能参考小子串的判断结果,即填表顺序很重要。
大家能够可以自己动手,画一下表格,相信会对「动态规划」作为一种[表格法」有一个更好的理解。

java

	public static String longestPalindrome2(String s) {
		int len = s.length();
		if (len < 2) {
			return s;
		}

		int maxLen = 1;
		int begin = 0;
		boolean dp[][] = new boolean[len][len]; // 定义状态:i-j 的子串是否是回文子串

		// 每次都会检查下标是否越界,因此先转化成 字符数组
		char[] charArray = s.toCharArray();
		// 枚举所有长度大于一的子串

		for (int i = 0; i < len; i++) {
			dp[i][i] = true; // 使对角线为true,因为单个字符一定为回文字符串
		}
		for (int j = 1; j < len; j++) {
			for (int i = 0; i < j; i++) {
				if (charArray[i] != charArray[j]) {
					dp[i][j] = false;
				} else {
					if (j - i < 3) {
						dp[i][j] = true;// 长度为2的子串回文
					} else {
						dp[i][j] = dp[i + 1][j - 1];
					}
				}

				// 只要dp[i][j]==true,便记录此刻的最大深度与起始地址
				if (dp[i][j] && j - i + 1 > maxLen) {
					maxLen = j - i + 1;
					begin = i;
				}
			}
		}
		return s.substring(begin, begin + maxLen);
	}

python

class Solution1:
    def longestPalindrome(self, s: str) -> str:
        size = len(s)
        if size < 2:
            return s

        dp = [[False for _ in range(size)] for _ in range(size)]

        max_len = 1
        start = 0

        for i in range(size):
            dp[i][i] = True

        for j in range(1, size):
            for i in range(0, j):
                if s[i] == s[j]:
                    if j - i < 3:
                        dp[i][j] = True
                    else:
                        dp[i][j] = dp[i + 1][j - 1]
                else:
                    dp[i][j] = False

                if dp[i][j]:
                    cur_len = j - i + 1
                    if cur_len > max_len:
                        max_len = cur_len
                        start = i
        return s[start:start + max_len]

方法三:中心扩散法

采用双指针两边夹,验证是否是回文子串。
除了枚举字符串的左右边界以外,比较容易想到的是枚举可能出现的回文子串的“中心位置”,从“中心位置”尝试尽可能扩散出去,得到一个回文串。
因此中心扩散法的思路是:遍历每一个索引,以这个索引为中心,利用“回文串”中心对称的特点,往两边扩散,看最多能扩散多远。枚举“中心位置”时间复杂度为O(N),从“中心位置扩散得到“回文子串的时间复杂度为O(N),因此时间复杂度可以降到0(N2)。.
在这里要注意一个细节: 回文串在长度为奇数和偶数的时候,“回文中心"的形式是不一样的

●奇数回文串的"中心"是一 个具体的字符,例如:文串”aba” 的中心是字符"b”;
●偶数回文串的中心是位于中间的两个字符的"空隙”,例如:文串” abba"的中心是两个”b”中间的那个空隙”。

我们可以设计一个方法,兼容以上两种情况:
1、如果传入重合的索引编码,进行中心扩散,此时得到的回文子串的长度是奇数;
2、如果传入相邻的索引编码,进行中心扩散,此时得到的回文子串的长度是偶数。
具体编码细节在以下的代码的注释中体现。

java

	public static String longestPalindrome3(String s) {
		int len = s.length();
		if (len < 2) {
			return s;
		}

		int maxLen = 1;
		String res = s.substring(0, 1);
		// 中心位置枚举到len-2即可
		for (int i = 0; i < len - 1; i++) {
			String oddStr = centerSpread(s, i, i);
			String evenStr = centerSpread(s, i, i + 1);
			String maxLenStr = oddStr.length() > evenStr.length() ? oddStr : evenStr;
			if (maxLenStr.length() > maxLen) {
				maxLen = maxLenStr.length();
				res = maxLenStr;
			}
		}
		return res;
	}

	private static String centerSpread(String s, int left, int right) {
		// TODO Auto-generated method stub
		//left==right的是时候,此时回文中心是一个字符。回文串的长度是奇数
		//right=left+1 的时候,此时回文中心是一个空隙,回文串的长度是偶数
		int len = s.length();
		int i = left;
		int j = right;
		while(i>=0&&j<len) {
			if(s.charAt(i)==s.charAt(j)){
				i--;
				j++;
			}else {
				break;
			}
		}
		//这里要小心,跳出while循环时,恰好满足s.charAt(i)!=s.charAt(j),因此不能取i,也不能取j
		
		return s.substring(i+1,j);
	}

python

class Solution2:
    def longestPalindrome(self, s: str) -> str:
        size = len(s)
        if size < 2:
            return s

        # 至少是 1
        max_len = 1
        res = s[0]

        for i in range(size):
            palindrome_odd, odd_len = self.__center_spread(s, size, i, i)
            palindrome_even, even_len = self.__center_spread(s, size, i, i + 1)

            # 当前找到的最长回文子串
            cur_max_sub = palindrome_odd if odd_len >= even_len else palindrome_even
            if len(cur_max_sub) > max_len:
                max_len = len(cur_max_sub)
                res = cur_max_sub

        return res

    def __center_spread(self, s, size, left, right):
        """
        left = right 的时候,此时回文中心是一个字符,回文串的长度是奇数
        right = left + 1 的时候,此时回文中心是一个空隙,回文串的长度是偶数
        """
        i = left
        j = right

        while i >= 0 and j < size and s[i] == s[j]:
            i -= 1
            j += 1
        return s[i + 1:j], j - i - 1

以上便是回文数的全部解法。下面是一种拓展方法,只需要了解思路就行了

方法四: Manacher 算法

Manacher算法是基于“中心扩散法",采用和kmp算法类似的思想,依然是"以空间换时间"。
Manacher算法,被中国程序员戏称为“马拉车算法。它转用于解决“最长文子串”问题,时间复杂度为O(N)。
维基百科中对于Manacher算法是这样描述的:

[Manacher(1975)]发现了一种线性时间算法,可以在列出给定字符串中从字符串头部开始的所有回文组。Apostolico, Breslauer & Galil (1995)发现,同样的算法也可以在任意位置查找全部最大回文子串,并且时间复杂度是线性的。因此,他们提供了-种时间复杂度为线性的最长回文子串解法。替代性的线性时间解决Jeuring (1994),Gusfield (1997)提供的,基于后缀树(suffix trees)。也存在已知的高效并行算法。

第1步:对原始字符串进行预处理(添加分隔符)
首先在字符串的首尾、相邻的字符中插入分隔符,例如"babad” 添加分隔符”#” 以后得到’ “#b#a#b#a#d#”。
对这-点有如下说明:

第1步:对原始字符串进行预处理(添加分隔符)
首先在字符串的首尾、相邻的字符中插入分隔符,例如"babad” 枷吩隔符”#” 以后得到” #b#a#b#a#d#”。
对这-点有如下说明:
1、分隔符是-一个字符,种类也只有一 个,并且这个字符一定不能是原始字符串中出现过的字符;
2、加入了分隔符以后,使得”间隙”有了具体的位置,方便后续的讨论,新字符串中的任意一个回文子串在原始字符串中
的- -定能找到唯-的一个回文子串与之对应,因此对新字符串的回文子串的研究就能得到原始字符串的回文子串;
3、新字符串的回文子串的长度一定是奇数;
4、新字符串的回文子串一定以分隔符作为两边的边界,因此分隔符起到哨兵”的作用。

第2步:计算辅助数组p
辅助数组p记绿了新字符串中以每个字符为中心的回子串的信息。
手动的计算方法仍然是“中心扩散法”,此时记录以当前字符为中心,向左右两边同时扩散,记绿能够扩散的最大步数。

下面是辅助数组| p的结论:辅助数组p的最大值是5,对应了原字符串” abbabb”的“最长回文子串”:。 这
个结论具有一般性,即:辅助数组 p的最大值就是“最长回文子串”的长度。
因此,我们可以在计算辅助数组p的过程中记录这个最大值,且记录最长回文子串。

最后,不经历风雨,怎能在计算机的大山之顶看见彩虹呢! 无论怎样,相信明天一定会更好!!!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

520,我会处理回文数了,你会了么?(dp+中心扩散) 的相关文章

  • Java中ArrayList的交集和并集

    有什么方法可以做到这一点吗 我正在寻找 但没有找到 另一个问题 我需要这些方法 以便我可以过滤文件 有些是AND过滤器 有些是OR过滤器 就像集合论中的那样 所以我需要根据所有文件和保存这些文件的联合 相交 ArrayList 进行过滤 我
  • 按键时关闭 ModalWindow

    我希望能够在用户按下某个键 在我的例子中是 ESC 时关闭 ModalWindow 我有一个用于按键的 Javascript 侦听器 它调用取消按钮 ID 的单击事件 jQuery modalWindowInfo closeButtonId
  • Mockito:如何通过模拟测试我的服务?

    我是模拟测试新手 我想测试我的服务方法CorrectionService correctPerson Long personId 实现尚未编写 但这就是它将执行的操作 CorrectionService将调用一个方法AddressDAO这将
  • 在内存中使用 byte[] 创建 zip 文件。 Zip 文件总是损坏

    我创建的 zip 文件有问题 我正在使用 Java 7 我尝试从字节数组创建一个 zip 文件 其中包含两个或多个 Excel 文件 应用程序始终完成 没有任何异常 所以 我以为一切都好 当我尝试打开 zip 文件后 Windows 7 出
  • 为 java 游戏创建交互式 GUI

    大家好 我正在创建一个类似于 java 中的 farmville 的游戏 我只是想知道如何实现用户通常单击以与游戏客户端交互的交互式对象 按钮 我不想使用 swing 库 通用 Windows 看起来像对象 我想为我的按钮导入自定义图像 并
  • 动态选择端口号?

    在 Java 中 我需要获取端口号以在同一程序的多个实例之间进行通信 现在 我可以简单地选择一些固定的数字并使用它 但我想知道是否有一种方法可以动态选择端口号 这样我就不必打扰我的用户设置端口号 这是我的一个想法 其工作原理如下 有一个固定
  • Spring AspectJ 在双代理接口时失败:无法生成类的 CGLIB 子类

    我正在使用Spring的
  • 如何在java中将一个数组列表替换为另一个不同大小的数组列表

    我有两个大小不同的数组列表 如何从此替换 ArrayList
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • 无法创建请求的服务[org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]-MySQL

    我是 Hibernate 的新手 我目前正在使用 Spring boot 框架并尝试通过 hibernate 创建数据库表 我知道以前也问过同样的问题 但我似乎无法根据我的环境找出如何修复错误 休眠配置文件
  • volatile、final 和synchronized 安全发布的区别

    给定一个带有变量 x 的 A 类 变量 x 在类构造函数中设置 A x 77 我们想将 x 发布到其他线程 考虑以下 3 种变量 x 线程安全 发布的情况 1 x is final 2 x is volatile 3 x 设定为同步块 sy
  • 在我的 Spring Boot 示例中无法打开版本 3 中的 Swagger UI

    我在 Spring Boot 示例中打开 swagger ui 时遇到问题 当我访问 localhost 8080 swagger ui 或 localhost 8080 root api name swagger ui 时出现这种错误 S
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • Eclipse 选项卡宽度不变

    我浏览了一些与此相关的帖子 但它们似乎并不能帮助我解决我的问题 我有一个项目 其中 java 文件以 2 个空格的宽度缩进 我想将所有内容更改为 4 空格宽度 我尝试了 正确的缩进 选项 但当我将几行修改为 4 空格缩进时 它只是将所有内容
  • Cucumber 0.4.3 (cuke4duke) 与 java + maven gem 问题

    我最近开始为 Cucumber 安装一个示例项目 并尝试使用 maven java 运行它 我遵循了这个指南 http www goodercode com wp using cucumber tests with maven and ja
  • 在java中为组合框分配键

    我想添加一个JComboBox在 Swing 中这很简单 但我想为组合中的每个项目分配值 我有以下代码 JComboBox jc1 new JComboBox jc1 addItem a jc1 addItem b jc1 addItem
  • 长轮询会冻结浏览器并阻止其他 ajax 请求

    我正在尝试在我的中实现长轮询Spring MVC Web 应用程序 http static springsource org spring docs 2 0 x reference mvc html但在 4 5 个连续 AJAX 请求后它会
  • CamcorderProfile.videoCodec 返回错误值

    根据docs https developer android com reference android media CamcorderProfile html 您可以使用CamcorderProfile获取设备默认视频编解码格式 然后将其
  • 如何防止在Spring Boot单元测试中执行import.sql

    我的类路径中有一个 import sql 文件 其中包含一些 INSERT 语句 当使用 profile devel 运行我的应用程序时 它的数据被加载到 postgres 数据库中 到目前为止一切正常 当使用测试配置文件执行测试时 imp
  • Spring Rest 和 Jsonp

    我正在尝试让我的 Spring Rest 控制器返回jsonp但我没有快乐 如果我想返回 json 但我有返回的要求 完全相同的代码可以正常工作jsonp我添加了一个转换器 我在网上找到了用于执行 jsonp 转换的源代码 我正在使用 Sp

随机推荐

  • android设备SD卡文件扫描与同步(暂备份)

    package com owo contentresolvermedia import java io File import java util ArrayList import android app Activity import a
  • 同一页面、不同页面监听localStorage变化

    当同源页面的某个页面修改了localStorage 其余的同源页面只要注册了storage事件 就会触发 所以 localStorage 的例子运行需要如下条件 同一浏览器打开了两个同源页面 其中一个网页修改了 localStorage 另
  • 简单易懂的隐马尔可夫模型(HMM)讲解

    学习目标 了解什么是马尔科夫链 知道什么是HMM模型 知道前向后向算法评估观察序列概率 知道维特比算法解码隐藏状态序列 了解鲍姆 韦尔奇算法 知道HMM模型API的使用 一 马尔科夫链 在机器学习算法中 马尔可夫链 Markov chain
  • Top-1错误率、Top-5错误率等常见的模型算法评估指标解析

    Top 1 错误率 指预测输出的概率最高的类别与人工标注的类别相符的准确率 就是你预测的label取最后概率向量里面最大的那一个作为预测结果 如过你的预测结果中概率最大的那个分类正确 则预测正确 否则预测错误 比如预测100张图像的类别 每
  • Spring Cloud Alibaba和Spring Cloud的区别

    目录 Spring Cloud Netflix 和 Spring Cloud 是什么关系 为什么有了Spring Cloud又出来个Spring Cloud Alibaba呢 Spring Cloud Alibaba都有哪些功能呢 Clou
  • JAVA——注解和反射

    注解的理解 引用b乎大佬的比喻 注解就像一张标签 给人贴标签是一种行为 会使一个人身上 的特性只有一部分被放大出来 但是换个角度 标签就是对事物行为的某些角度的评价与解释 从代码的角度上看 注解就是对于代码中需要拥有某些特别意义的功能的部分
  • 计算个人所得税

    输入一个职工的月薪salary 输出应交的个人所得税tax 保留2位小数 tax rate salary 850 当 salary lt 850 时 rate 0 0 当 850 lt salary lt 1350 时 rate 0 05
  • centos 6 yum源不可用安装报YumRepo Error: All mirror URLs are not using ftp, http[s] or file

    项目场景 centos6 5 使用yum安装资源时 报如下错误 1 YumRepo Error All mirror URLs are not using ftp http s or file 解决方案 修改 etc yum repos d
  • Spring Data 与MongoDB 集成四:操作篇(查询)

    本文转载至 http blog csdn net congcong68 article details 47183209 一 简介 spring Data MongoDB提供了org springframework data mongodb
  • 论文阅读:Improved Denoising Diffusion Probabilistic Models

    本文是对ddpm简单的修改 但是能提高ddpm的性能 论文下载地址 https proceedings mlr press v139 nichol21a html 我们发现反向过程中可学习的方差允许一个数量级的采样 样本质量的差异可以忽略不
  • AOP中的代理对象

    先要了解spring容器初始化过程中Bean的生命周期 如果spring在启动过程中加上了 Transiation注释的话 spring会生成一个代理对象 来做事务控制 我们从容器中取出来的对象是代理对象 代理对象在执行方法之前会开启事务管
  • 浏览器兼容性问题解决

    样式兼容性 css 方面 解决方法 可以通过 Normalize css 抹平差异 也可以定制自己的 reset css 全局重置样式 firefox浏览器不支持cursor hand显示手型 解决方法 统一使用cursor pointer
  • C# 用Microsoft.Office.Interop.PowerPoint类库操作PPT

    前言 最近由于项目需求 需要使用此类库对PPT进行操作 1 引用 Microsoft Office Interop PowerPoint和 Microsoft Office Core 2 PPT操作 打开PPT PPT应用程序变量 Appl
  • vue如何获取当前路径url及参数

    有时候开发需要获取当前url的参数 完整url可以用 window location href 路由路径可以用 this route path 路由路径参数 this route params params是参数名称 this route
  • Django-模型层(单表操作)

    目录 1 ORM简介 2 单表操作 2 1创建表 2 2添加表纪录 2 3查询表纪录 2 4删除表纪录 2 5修改表纪录 1 ORM简介 MVC或者MVC框架中包括一个重要的部分 就是ORM 它实现了数据模型与数据库的解耦 即数据模型的设计
  • 2019 前端框架对比及评测

    Jacek Schae 原作 授权 LeanCloud 翻译 我们将基于 RealWorld 示例应用对比前端框架 RealWorld 示例应用的特点 RealWorld 应用 比待办事项类应用更复杂 通常待办事项类应用不足以传达足够多的知
  • 最详细的Python接单思路和方法

    首先讲下python爬虫怎么接单挣钱 Python爬虫挣钱方法大致如下 有些需要的技术并不难 这种大部分都可以做 有些可能对技术要求比较高 门槛相对就高一点 爬虫技术挣钱方法1 接外包爬虫项目 这是网络爬虫最通常的的挣钱方式 通过外包网站
  • LeetCode-环形链表-简单

    标题 141环形链表 简单 题目 给你一个链表的头节点 head 判断链表中是否有环 如果链表中有某个节点 可以通过连续跟踪 next 指针再次到达 则链表中存在环 为了表示给定链表中的环 评测系统内部使用整数 pos 来表示链表尾连接到链
  • IDEA中配置Maven常见问题每次都需要更改setting设置,否则使用默认Maven,完美解决Maven的配置问题!

    废话不说 直接上图 你是否也遇到这种情况呢 创建maven无模板项目时 maven总是idea自带 如何解决呢 点开系统setting 1 取消默认打开上一次项目 2 重启IDEA 在全局设置就可以了 完美解决 创作不易 问题解决的给个鼓励
  • 520,我会处理回文数了,你会了么?(dp+中心扩散)

    给定一个字符串 s 找到 s 中最长的回文子串 你可以假设 s 的最大长度为 1000 示例 1 输入 babad 输出 bab 注意 aba 也是一个有效答案 示例 2 输入 cbbd 输出 bb 方法一 暴力匹配 Brute Force