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

 

你可能感兴趣的:(poj)