zoukankan      html  css  js  c++  java
  • POJ 3974:Palindrome

    Description

      Andy是计算机系的非常聪明的一个学生,她参加了一门算法课,教授问了学生一个简单的问题:“你能不能高效地在一个字符串中找到最长回文子串呢?”。
      如果一个字符串从前往后读和从后往前读是一样的,则字符串被称为是回文。比如“madam”是回文,而“acm”不是回文。
      学生意识到这是一个经典的问题,但是他们只能够想到列举所有的子串并且判断这个子串是不是回文,很明显这个算法并不高效,这时Andy举手说:“我有一个更好的算法”,在他开始解释他的思想之前他停了一会,并说:“我有了一个更好的算法”。
      如果你认为你知道Andy的最后解决方案,那么解决他吧。给定一个长度至多为1,000,000 字符串,输出最长回文子串的长度。

    Input

    你的程序将会被至多30个测试用例测试,每个测试用例是每行一个长度至多1000000的小写字符串。输入终止于字符串“END”。

    Output

    每个测试用例都输出测试用例的编号和最长回文子串的长度。

    Sample Input

    abcbabcbabcba
    abacacbaaaab
    END

    Sample Output

    Case 1: 13
    Case 2: 6

    Source

    Manacher算法即可在 O(n) 时间内找到最长回文子串,这里要注意是求“Longest Palindrome Substring” 而不是 “Longest Palindrome Subsequence”。

     1 import java.util.Scanner;
     2 
     3 public class Main {
     4     public static int longestPalidromeSubstring(String str){
     5         char[]t = preprocess(str);
     6         int p[] = new int[t.length];
     7         int center = 0;
     8         int right = 0;
     9         int mirror = 0;
    10         for(int i=1;i<t.length-1;i++){
    11             mirror = 2*center - i;
    12             if(right>i){
    13                 p[i] = Math.min(right - i, p[mirror]);
    14             }
    15             while(t[i+(1+p[i])]==t[i-(1+p[i])]){
    16                 p[i]++;
    17             }
    18             if(i+p[i]>right){
    19                 center = i;
    20                 right = i+p[i];
    21             }
    22         }
    23         int max = 0;
    24         for(int i=1;i<t.length-1;i++){
    25             if(p[i]>max) max = p[i];
    26         }
    27         return max;
    28     }
    29     private static char[] preprocess(String str) {
    30         char[] ch = new char[2*str.length()+ 3];
    31         ch[0] = '$';
    32         ch[2*str.length()+2] = '@';
    33         for(int i=0;i<str.length();i++){
    34             ch[2*i+1] = '#';
    35             ch[2*i+2] = str.charAt(i);
    36         }
    37         ch[ch.length-2] = '#';
    38         return ch;
    39     }
    40     public static void main(String[] args) {
    41         Scanner in = new Scanner(System.in);
    42         String line = null;
    43         int count = 0;
    44         while(!(line=in.nextLine()).equals("END")){
    45             System.out.println("Case "+(++count)+": "+longestPalidromeSubstring(line));
    46         }
    47     }
    48 }
    Source
    作者:xiazdong
    出处:http://blog.xiazdong.info
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    php yield学习笔记(一)
    EasySwoole的ContextManager的分析和使用
    Easyswoole的WaitGroup和Csp组件的分析和使用
    Laravel Event的分析和使用
    Laravel驱动管理类Manager的分析和使用
    Laravel Exception结合自定义Log服务的使用
    vue基础
    vue.js
    改善项目组织
    MongoDB 4.0版
  • 原文地址:https://www.cnblogs.com/xiazdong/p/3116002.html
Copyright © 2011-2022 走看看