Manacher算法: 最长回文子串O(N)时间内求解

本文深入解析Manacher算法,一种高效求解最长回文子串问题的方法。通过代码实例展示算法的实现细节,并讨论了实现过程中可能遇到的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    最近在leetcode上刷题,看到的Longest Palindromic Substring问题,leetcode上给出了5种方法(暴力法、最长公共子串法、DP、中心扩展法)+Manacher算法。5种方法中Manacher算法是唯一一个可以在O(N)时间复杂度内求解最长回文子串的算法。leetcode官方解答没有给出算法的描述,后面搜索了网上的博客资源,才看懂。

   

整理Manacher算法,主要是出于两点:1、惊叹于算法的巧妙;2、记录自己实现中遇到的一些问题,希望有机会跟各位进行交流。


1)算法的详细过程与精妙之处,网上的大牛已经进行了详尽的整理。在此,不再赘述!推荐大家参照:

Manacher算法:求解最长回文字符串,时间复杂度为O(N)

最长回文子串


2)重点整理自己在实现过程中的疑问。

在上述的博文中,作者都之处为了防止越界,在初始化的过程中分别在字符串首部和尾部插入“$”及“\0”。但是在笔者自己实现的过程中,发现:字符首部和尾部特意插入“$”及“\0”并不是必须的!

话不多说,代码附上!(代码写的比较挫,大家凑合看)

public class Solution {
	public String longestPalindrome(String s) {
        	
		int len = s.length();
		len = 2 * len + 1;
		
		//initialization 
		char array[] = new char[len];
		//array[0] = '$';
		
		for(int i = 1, j = 0; i < len; j++, i = i + 2){
			array[i] = s.charAt(j);
			array[i-1] = '#'; 
		}
		array[len - 1] = '#';		
		
		//algorithm
		int mx = 0;
		int id = 0;
		int p[] = new int[len];
		for(int i = 0; i < len; i ++){
			
			if( i < mx){
				p[i] = p[2*id - i] < mx - i ? p[2*id - i]: mx - i; 
			}else{
				p[i] = 1;
			}
			
			for(; (i + p[i] < len ) && ( i - p[i] >= 0) && (array[i + p[i]] == array[i - p[i]]); p[i]++){
			
			}
			
			if( i + p[i] > mx){
				mx = i+p[i];
				id = i;
			}
		}
		
		
		//max rad
		int rad = 1;
		int mid = 0;
		for(int i = 0; i < len ; i++){
			if(p[i] > rad){
				mid = i;
				rad = p[i];
			}
		}
		
		char res[] = new char[ rad - 1];
		int num = 0;
		for( int i = mid - rad + 1; i < mid + rad - 1; i++){
			if(array[i] != '#'){
				res[num++] = array[i];
			}
		}
		
		
		String subs = new String(res);
		return subs;
	}
        
 }

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值