首页 > 试题广场 >

Manacher算法进阶问题

[编程题]Manacher算法进阶问题
  • 热度指数:588 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定一个字符串str,想通过添加字符的方式使得str整体都变成回文字符串,但要求只能在str的末尾添加字符,请返回在str后面添加的最短字符串
[举例]
str = "abcd123321",在必须包含最后一个字符的情况下,最长的回文子串是"123321",之前不是最长回文子串的部分是'abcd",所以末尾应该添加的部分就是"dcba"。
[要求]
如果str的长度为N,解决进阶问题的时间复杂度为O(N).
保证输入数据无回文串

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


输出描述:
输出一个字符串。
示例1

输入

abcd123321

输出

dcba

说明

添加后的字符串为abcd123321dcba
示例2

输入

ababab

输出

a

备注:
设N表示输入字符串的长度
保证输入字符中只含有小写字母及数字
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.*;
 
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 C = -1;
        int R = -1;
        int[] pArr = new int[str.length];
        for(int i=0; i<str.length; i++){
            pArr[i] = i<R ? Math.min(pArr[2*C-i],R-i) : 1;
            while(i+pArr[i]<str.length && i-pArr[i]>-1){
                if(str[i-pArr[i]]==str[i+pArr[i]]){
                    pArr[i]++;
                }else{
                    break;
                }
            }
            if(i+pArr[i]>R){
                R=i+pArr[i];
                C = i;
            }
        }
        int index= C-pArr[C];
        StringBuilder sb = new StringBuilder();
        while(index>=0){
            sb.append(str[index]=='#' ? "" : str[index]);
            index--;
        }
        System.out.println(sb.toString());
    }
     
    private static char[] preprocessing(char[] str) {
        StringBuilder sb = new StringBuilder();
        for(char c: str) sb.append("#").append(c);
        sb.append("#");
        return sb.toString().toCharArray();
    }
}

发表于 2022-01-26 20:20:41 回复(0)

问题信息

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

热门推荐

通过挑战的用户

查看代码