马拉松算法 - 最长回文子串-java

本文介绍了如何运用马拉松算法来找出一个字符串中的最长回文子串,并提供了详细的Java代码实现。算法解释链接指向深入理解马拉松算法的资源。

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

马拉松算法 - 最长回文子串-java

算法解释的链接
链接: link.

下面是java代码。

// An highlighted block
class Solution {
    public String longestPalindrome(String s) {
        String str = preHandleString(s);
        int len = str.length();
        //当前的最右和最右的中心点
        int right = 0;
        int rightCenter = 1;
        //用于保存以i为中心的时候的最长半径
        int[] halfLenArr  = new int[len];
        //历史的最长子串的中心和长度
        int center = 0;
        int longestHalf = 0;
        for(int i = 1 ;i < len - 1; i ++){
        	//需不需要扩展
            boolean needCala = true;
            if(right > i){
                int left = 2 * rightCenter - i;
                halfLenArr[i] = Math.min(halfLenArr[left], right - i);
                if(i + halfLenArr[i] < right ){
                	//如果当前的中心加半径在最右的范围内,则不用扩展,因为扩展后必不回文
                    needCala = false;
                }
            }
            if(needCala){
            	//这里不用考虑边界是因为初始化字符串的处理
                while (str.charAt(i - halfLenArr[i]) == str.charAt(i + halfLenArr[i])){
                    halfLenArr[i] ++;
                }
                halfLenArr[i] --;
                right = i + halfLenArr[i];
                rightCenter = i;
                if(halfLenArr[i] > longestHalf){
                    center = i;
                    longestHalf = halfLenArr[i];
                }
            }
        }
        
        //取结果需要跳过中间的#,所以是每次跳两格
        StringBuffer stringBuffer = new StringBuffer();
        for(int i = center - longestHalf + 1; i < center + longestHalf;i += 2 ){
            stringBuffer.append(str.charAt(i));
        }
        return stringBuffer.toString();
    }
	
	//初始化字符串
    private String preHandleString(String s){
        StringBuffer stringBuffer = new StringBuffer();
        int length = s.length();
        //添加@和$是为了上面循环不用考虑边界问题,因为到边界就会不等于了
        stringBuffer.append("@#");
        for(int i = 0 ; i < length ; i ++){
            stringBuffer.append(s.charAt(i));
            stringBuffer.append('#');
        }
        stringBuffer.append("$");
        return stringBuffer.toString();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值