总结最长回文子串的几种做法 Longest Palindrome Substring

最长回文子串的五种求法(暴力、中点扩散、DP、hash+二分、Manacher) 最长回文子串暴力枚举法(O(n3)O(n^3)O(n3))中点扩散算法(O(n2)O(n^2)O(n2))动态规划(O(n2)O(n^2)O(n2))hash+二分(O(nlog n)O(nlog\ n)O(nlog n)) 暴力枚举法(O(n3)O(n^3)O(n3)) 暴力大法好,枚举字符串的始位置和末位值,再判断始位置和末位值之间的字符串是否为回文串,这种做法的时间复杂度为O(n^3)。 中点扩散算法(O(n2)O(n^2)O(n2)) 由于回文串是对称的,所以我们可以枚举所 阅读详情

题目是:找出一个字符串中的最长回文子串。

例如:abcbcbb 的最长回文子串是 bcbcb

首先一种常见的错误方法是把原字符串S倒转过来成为S‘,以为这样就将问题转化成为了求S和S’的最长公共子串的问题。反例S="abacdfgdcaba",若按这种解法得到答案是:"abacd",显然不是回文,而正确答案是"aba"


PS:这也是LeetCode的一道题:http://blog.youkuaiyun.com/fightforyourdream/article/details/15025663


下面总结一下四种解法:(面试时推荐中心展开法)

1)暴力法:Time:O(n^3), Space:O(1)

2)DP法:Time:O(n^2), Space:O(n^2)










http://faculty.utpa.edu/liuy2/algorithmGroup.html



3)中心展开法:Time:O(n^2), Space:O(n)  ***推荐面试时用!!!


http://blog.163.com/zhaohai_1988/blog/static/2095100852012716105847112/


4)Manacher算法:Time:O(n),Space: O(n)   (精妙但较麻烦)

http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html



下面是实现代码:


package String;

public class LongestPalindromeSubstring {

	
	// 暴力法 Time Complexity: O(n^3)
	public static String longestPalindromeBruteForce(String s) {
		String longest = "";
		if(s.isEmpty()) {
			return longest;
		}
		
		for(int i=0; i<s.length(); i++) {		// 开始位置
			for(int j=i; j<s.length(); j++) {	// 结束位置
				String substr = s.substring(i, j+1);
				if(j-i+1 > longest.length() && isPalindrome(substr)) {
					longest = substr;
				}
			}
		}
		return longest;
	}
	
	// O(n) 检查是否为回文
	private static boolean isPalindrome(String s) {
		int len = s.length();
		for(int i=0; i<=len/2; i++) {
			if(s.charAt(i) != s.charAt(len-1-i)) {
				return false;
			}
		}
		return true;
	}
	
	// ===========================================
	// 动态规划1 时间复杂度O(N2), 空间复杂度O(N2)
	public static String longestPalindromeDP1(String s) {
		int len = s.length();
		int longestBegin = 0;
		int maxLen = 1;
		boolean[][] isPalindrome = new boolean[len+1][len+1];
		
		for(int i=0; i<len; i++) {
			isPalindrome[i][i] = true;
		}
		
		for(int i=0; i<len-1; i++) {
			if(s.charAt(i) == s.charAt(i+1)) {
				isPalindrome[i][i+1] = true;
				longestBegin = i;
				maxLen = 2;
			}
		}
		
		for(int l=2; l<=len; l++) {			// 回文子串的长度
			for(int i=0; i<len-l+1; i++) {	// 回文子串的开始位置
				int j = i+l-1;					// 回文子串的结束位置
				if(isPalindrome[i+1][j-1] && s.charAt(i) == s.charAt(j)) {
					isPalindrome[i][j] = true;
					longestBegin = i;
					maxLen = l;
				}
			}
		}
		
		return s.substring(longestBegin, longestBegin+maxLen);
	}
	
	
	// ===========================================
	// 中心展开法 时间复杂度O(N2), 空间复杂度O(1)
	public static String longestPalindromeExpand(String s) {
		int len = s.length();
		if(len == 0) {
			return "";
		}
		String longest = s.substring(0, 1);
		for(int i=0; i<len; i++) {
			// 当回文为奇数长度时
			String p1 = 	expandAroundCenter(s, i, i);
			if(p1.length() > longest.length()) {
				longest = p1;
			}
			// 当回文为偶数长度时
			String p2 = expandAroundCenter(s, i, i+1);
			if(p2.length() > longest.length()) {
				longest = p2;
			}
		}
		return longest;
	}
	
	// c1, c2为展开的中心位置
	private static String expandAroundCenter(String s, int c1, int c2) {
		int l = c1, r = c2;
		int len = s.length();
		// 如果检查位置相等,则分别往左右展开
		while(l>=0 && r<=len-1 && s.charAt(l)==s.charAt(r)) {
			l--;
			r++;
		}
		return s.substring(l+1, r);		// 回文子串
	}
	
	
	// ===========================================
	// Manacher算法, Time: O(N), Space: O(N)
	// http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html
	public static String longestPalindromeManacher(String s) {
		String T = preProcess(s);
		int len = T.length();			// 经过变化后,len总是为奇数长
		int[] P = new int[len];		// P数组存放在某index下的回文半径长度
		int C = 0, R = 0;		// C为最长回文子串的中心位置,R为当前最长回文子串的右边界位置
		for(int i=1; i<len-1; i++) {
			int iMirror = C - (i-C);	// 计算i的对应回文左边匹配位置i' 
			
			/*
			 if (R - i > P[iMirror]) 
			    P[i] = P[iMirror];
			else 				  // P[iMirror] >= R - i
			    P[i] = R - i;   // P[i] >= R - i,取最小值,之后再匹配更新。
			
			可简写成P[i] = (R > i) ? Math.min(R-i, P[iMirror]) : 0;
			 */
			P[i] = (R > i) ? Math.min(R-i, P[iMirror]) : 0;
			
			// 贪心拓展以i为回文中心的回文子串
			while(T.charAt(i+1+P[i]) == T.charAt(i-1-P[i])) {
				P[i]++;
			}
			
			// 如果以i为中心的回文扩展超过了R,则我们找到一个新的更长回文子串
			// 因此 更新 最长回文子串的中心和右边界
			if(P[i] > R-i) {
				C = i;
				R = i + P[i];
			}
		}
		
		// 现在P[i]数组里存放了以i为中心的回文子串长度,用打擂台方式找到最长者
		int maxLen = 0;
		int centerIndex = 0;
		for(int i=1; i<len-1; i++) {
			if(P[i] > maxLen) {
				maxLen = P[i];
				centerIndex = i;
			}
		}
		
		int start = (centerIndex-1-maxLen)/2;
		int end = start + maxLen;
		return s.substring(start, end);
	}
	
	// 把s转换成T,如s="abba",则T="^#a#b#b#a#$"
	// ^和$加在字符串首尾用来避免边界检查
	private static String preProcess(String s) {
		int len = s.length();
		if(len == 0) {
			return "^$";
		}
		String ret = "^";
		for(int i=0; i<len; i++) {
			ret += "#" + s.substring(i, i+1);
		}
		ret += "#$";
		return ret;
	}
	
	
	public static void main(String[] args) {
//		String s = "abacdfgdcaba";
		String s = "abcbcbb";
		System.out.println(longestPalindromeBruteForce(s));
		System.out.println(longestPalindromeDP1(s));
		System.out.println(longestPalindromeExpand(s));
		System.out.println(longestPalindromeManacher(s));
	}

}




最后:

这道题其实还可以用后缀树(Suffix Tree)来做,但是复杂度(O(nlogn))超过Manacher算法,并且实现起来更加麻烦,所以暂时没添加进来。




每天一道LeetCode-----最长回文子串/序列,从头开始的最长回文子串长度 原题链接 Longest Palindromic Substring 意思是找到最长的回文子串,注意子串和子序列的区别蛮力法就将每个可能的子串都找出来判断是否是回文子串,找最大的那一个,速度上慢的吓人,光找子串的速度就到O(n2)了,所以此处需要找到一个简单的方法找到回文子串。 既然回文子串是从中心开始向两边延伸时,左右两边相同,那么就可以从每个字符开始都向两边延伸,看能找到的最长回文子串是 阅读详情

相关推荐

基于Arduino与脑电模块的意念控制LED灯环实现

脑机接口(BCI)技术通过采集和处理脑电信号,实现人脑与外部设备的直接交互。其核心原理是利用传感器捕捉大脑活动产生的微弱电信号,经过放大、滤波和特征提取,转换为可识别的指令。这项技术在医疗康复、神经反馈训练和人机交互等领域具有重要价值。本文聚焦于一个具体的工程实践:使用消费级NeuroSky TGAM模块采集专注度与放松度数据,通过Arduino平台解析信号,并驱动WS2812B LED灯环实现实时可视化反馈。项目涵盖了硬件选型、电路搭建、数据解析和光效映射等关键环节,为脑机接口入门和嵌入式开发提供了完整的

weixin_28721917的博客 279

【LeetCode】5.最长回文子串

题目描述: 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。 1.最长公共子串法     将字符串s反转,变成s',找到s和s'之间的最长公共子串,一般这个公共子串就是答案,但是在s的其他部分如果存在非回文子串的反向副本(比如s=“abacdfgdcaba”,s'=“abacdgfdcaba”,最长公共子串为“abacd”,但这不是回文),所以在找到最长...

小咸鱼的博客 201

THB6128步进电机驱动芯片介绍

THB6128芯片也称为步进电机驱动芯片,采用BiCDMOS工艺,IC管脚间距为1mm的小型MFP30KR封装而成。

weichen_78的博客 7182

最长回文子串(longest-palindromic-substring)——动态规划DP

题目 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例 1: 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。 示例 2: 输入: "cbbd" 输出: "bb" 代码 解法 1: 暴力破解 暴力求解,列举所有的子串,判断是否为回文串,保存最长的回文串。 // 暴力解法 public String longest...

mirana的专栏 2315

NTFS分区变成RAW别乱修!正确数据恢复与修复方法详解

文件系统是操作系统管理存储数据的核心机制,NTFS作为Windows主流文件系统,一旦分区识别异常,常会显示为RAW格式。分区变RAW通常意味着文件系统入口信息损坏,而非数据物理消失,但若采用错误的修复方式,如直接对RAW分区执行chkdsk /f,可能因系统无法正确识别文件系统结构,导致写入操作落在错误偏移位置,二次破坏本可恢复的数据。正确的处理思路是:先停止一切写入操作,通过扇区级镜像备份保留原始现场,再分析DBR、分区表及$MFT状态,依据诊断结果选择修复或深度扫描恢复。实际排查中,常见问题如DBR记

weixin_31155097的博客 134

第12篇: COZE 实操【自动生成每日英语短视频】详细制作流程

通过以上详细流程,你可以利用 Coze 智能体高效生成每日英语短视频。在实际操作中,若遇到问题或有新的创意需求,欢迎随时与我交流,进一步优化视频制作流程。从左侧节点库中拖拽 “开始” 节点到画布中央,设置主题输入框(如输入 “日常购物英语”),方便后续根据不同主题生成视频。2. 选题策划节点​。3. 内容生成节点​。4. 画面生成节点​。5. 配音生成节点​。6. 音频匹配节点​。7. 视频合成节点​。

AI实操部署-深耕AI领域老菜鸟! 2071

数据结构算法题/最长回文子串

回文表示字符串正向和反向是相同的。例如a, aba, abccba 一、暴力法 最容易想到的就是暴力破解,求出每一个子串,之后判断是不是回文,找到最长的那个。 求每一个子串时间复杂度O(N^2), 判断子串是不是回文O(N),两者是相乘关系,所以时间复杂度为O(N^3)。 二、动态规划 下面介绍动态规划的方法,使用动态规划可以达到最优的 O(n2) 复杂度。   令 dp[i][j] ...

fkyyly的专栏 493

UE5在Ubuntu22.04.4下的高效开发环境配置指南

本文详细介绍了在Ubuntu 22.04.4系统上配置UE5高效开发环境的完整指南,包括系统准备、显卡驱动安装、UE5引擎编译与配置、开发工具链设置以及性能优化技巧。通过逐步指导,帮助开发者快速搭建稳定的UE5开发环境,解决常见问题,提升开发效率。

weixin_29251131的博客 383

最长回文子串(Longest Palindromic Substring)——三种时间复杂度的解法

    子串:小于等于原字符串长度由原字符串中任意个连续字符组成的子序列    回文:关于中间字符对称的文法,即“aba”(单核)、“cabbac”(双核)等    最长回文子串:1.寻找回文子串;2.该子串是回文子串中长度最长的。一、O(n^3)时间复杂度方法——暴力求解1.思想:    1)从最长的子串开始,遍历所有该原字符串的子串;    2)每找出一个字符串,就判断该字符串是否为回文;  ...

qq_32354501的博客 6万+

LMX2820即时校准实战:从失锁到稳定锁频的完整指南

本文详细解析了LMX2820锁相芯片在高频段(11.3-22.6GHz)易出现随机失锁问题的根源,并提供了即时校准(InstCal)的完整实战指南。通过寄存器编程、Index例程和校准配置的关键步骤,确保从失锁到稳定锁频的高可靠性,大幅提升射频合成器在通信与测试测量应用中的性能。

bert9linguist的博客 958

卡尔曼滤波器中的Q,R

对于系统状态的估计(滤波结果)所使用的信息来源于两个方面,一个是对系统状态演变模型的了解,包括系统转移矩阵和输入控制矩阵,输入孔质量等,另一方面来自于对系统状态的观测量。从上面公式来看,真正所要滤波得到的结果来自于公式(4)中的系统状态估计值x的某些分量,公式(4)的结果是由公式(1)所得到的状态预测值和来自观测量y计算得到的。所以,在不同算法中,R, Q的取值根据反应的不同量纲,可以有很大的变化,但它们的比值会决定了滤波值应该更多来自于系统模型演化的信息,还是来自于观察信号信息。

qq_43416206的博客 500

最长回文子串(Longest Palindrome Substring)--Manacher算法O(n)

Problem Description: 给出一个只由小写英文字符a,b,c...y,z组成的字符串S,求S中最长回文串的长度. 回文就是正反读都是一样的字符串,如aba, abba等 下面介绍一种复杂度只有O(n)的Manacher算法: 首先用一个非常巧妙的方式,将所有可能的奇数/偶数长度的回文子串都转换成了奇数长度:在每个字符的两边都插入一个特殊的符号。比如 abba 变成

ZkvIA的博客 2770

视觉Transformer实战 | Transformer详解与实现

本文系统介绍了 Transformer 架构的核心原理与实现。相比传统 RNN 和 CNN,Transformer 凭借自注意力机制有效捕捉序列中的长距离依赖关系,支持并行训练,显著提升效率。其核心创新在于通过查询、键、值向量计算注意力权重,理解单词间的语义关联。架构包含编码器-解码器结构:编码器通过多头自注意力和前馈网络提取输入特征;解码器利用掩码自注意力和交叉注意力生成输出。本文使用 PyTorch 实现了缩放点积注意力、位置编码、层归一化等关键模块,并构建了完整的 Transformer 模型。

盼小辉丶的博客 4万+

【Leetcode】Longest Palindrome Substring

【题目】Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 【题解】 Mana

ljffdream的专栏 486

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

最长公共回文子串(Longest_Common_Palindrome_Substring)

一、基本概念 最长公共回文子串(Longest_Common_Palindrome_Substring):两个字符串中最长的公共子串并且是回文字符串的子串 二、算法 三、代码 #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull;...

无限迭代中...... 990

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Longest Palindrome-Substring

fromhttps://www.cxyxiaowu.com/2869.html 作者:李威 题目描述 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。 示例1: 输入:"babad" 输出:"bab" 注意:"aba"也是一个有效答案。 示例2: 输入:"cbbd" 输出:"bb" 方法一:暴力匹配 (Brute Force) 根据回文子串的定义,枚举所有长度大于等于2的子串,依次判断它们是否是回文。在具体实现时,可以只针...

maxzcl的博客 268

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

最长回文字串 (The longest palindrome substring)

这两天去学了一下,觉得下面那篇文章写的很好,有例子,比较容易懂,所以转一下。 以下内容来自:hihoCoder: 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。 这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一...

123

Longest Palindrome Substring

Given a strings, find the longest palindromic substring ins. You may assume that the maximum length ofsis 1000. Example 1: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. Exa...

leetcode 解题思路 248

5 longest palindrome substring

第一眼看这题,只觉得要从中间开始向两端延伸,通过扫一遍所有的字母来实现。。。 但是代码不是特别好写,因为有奇数和偶数的两种情况。。。 既然这样,那就设计一个helper 方法,然后引入两个index,可以是相同的,代表奇数长度substring,也可以是相邻的,代表偶数长度substring public class Solution{ private int lo, maxLen

laserljy123的博客 466

leetcode5. Longest Palindromic Substring最长回文子串多种解法-待补充

原题链接 题目的意思不过多的赘述,这里先给出三种解法:暴力解,马拉车,一种巧解 暴力解 写一个判断回文的函数,两重循环判断最长子串(这种方法在字符串过长时可能会栈溢出) class Solution: def longestPalindrome(self, s: 'str') -&amp;amp;gt; 'str': if len(s) &amp;amp;lt; 2: return...

weixin_42156928的博客 207

longest Palindrome substring

class Solution { public: string longestPalindrome(string s) { // Start typing your C/C++ solution below // DO NOT write int main() function int len = s.size(); int

benbenab的专栏 515

[Leetcode刷题] 第5题 Longest Palindromic Substring 最长回文子串

题目: Given a strings, find the longest palindromic substring ins. You may assume that the maximum length ofsis 1000. Example 1: Input: "babad" Output: "bab" Note: "aba" is also a valid answer. ...

LynnZhang7的博客 215

[LeetCode] Longest Palindrome Substring 详细分析

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. 面DP题的考官都是神经病。。(吐

jhbxlx的专栏 1860

G.Longest Palindrome Substring

链接:https://ac.nowcoder.com/acm/contest/908/G 题意: A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. For example, ”a”、”aba”...

weixin_33779515的博客 114

【Leetcode】Longest palindrome substring

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring. ——————————————————

qbt4juik的专栏 495
上一篇: Linux下zip一个文件夹folder/directory
下一篇: 一些我推荐的和想上的网络课程(Coursera, edX, Udacity)
chiiis
博客等级 码龄14年 422粉丝 429原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值