新浪微博 Github

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

 

posted @ 2013-06-03 19:44  xiazdong  阅读(662)  评论(0编辑  收藏  举报