首页 > 试题广场 >

Manacher算法

[编程题]Manacher算法
  • 热度指数:1092 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个字符串str, 返回str中最长回文子串的长度
[举例]
str=“123”。其中的最长回文子串“1”或者“2”或者“3”,所以返回1。
str=“abc1234321ab”。其中的最长回文子串“1234321”,所以返回7。
[要求]
如果str的长度为N,解决原问题的时间复杂度都达到O(N).

输入描述:
输入为一个字符串str


输出描述:
输出一个整数表示最长回文子串的长度
示例1

输入

123

输出

1
示例2

输入

abc1234321ab

输出

7

备注:
设N表示输入字符串的长度
保证输入字符中只含有小写字母及数字
题目叫Manacher算法,那就老老实实写个Manacher算法来求解
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String s = br.readLine();
        char[] str = preprocessing(s.toCharArray());     // 预处理原始字符串,往每个字符之间加#
        int[] radius = new int[str.length];
        int R = -1, C = -1;       // 最远右边界(下一位置)及其对应的中心位置
        int max = 1;
        for(int i = 0; i < str.length; i++){
            radius[i] = i < R? Math.min(radius[2*C - i], R - i): 1;      // i在R内部或不在R内部的情况下,不需要检查的范围
            while(i + radius[i] < str.length && i - radius[i] >= 0){     // 没有越界
                if(str[i + radius[i]] == str[i - radius[i]]){
                    // 往外扩成功了半径就增加
                    radius[i] ++;
                }else{
                    break;
                }
            }
            // 最远右边界变大时要更新其位置和中心
            if(i + radius[i] > R){
                R = i + radius[i];
                C = i;
            }
            max = Math.max(max, radius[i]);
        }
        System.out.println(max - 1);
    }
    
    private static char[] preprocessing(char[] str) {
        StringBuilder sb = new StringBuilder();
        for(char c: str) sb.append("#").append(c);
        sb.append("#");
        return sb.toString().toCharArray();
    }
}

发表于 2021-11-17 21:28:27 回复(0)

问题信息

上传者:小小
难度:
1条回答 2709浏览

热门推荐

通过挑战的用户

查看代码