#1032 : 最长回文子串

时间限制:1000ms
单点时限:1000ms
内存限制:64MB

描述

   小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进。

   这一天,他们遇到了一连串的字符串,于是小Hi就向小Ho提出了那个经典的问题:“小Ho,你能不能分别在这些字符串中找到它们每一个的最长回文子串呢?”

   小Ho奇怪的问道:“什么叫做最长回文子串呢?”

   小Hi回答道:“一个字符串中连续的一段就是这个字符串的子串,而回文串指的是12421这种从前往后读和从后往前读一模一样的字符串,所以最长回文子串的意思就是这个字符串中最长的身为回文串的子串啦~”

   小Ho道:“原来如此!那么我该怎么得到这些字符串呢?我又应该怎么告诉你我所计算出的最长回文子串呢?

   小Hi笑着说道:“这个很容易啦,你只需要写一个程序,先从标准输入读取一个整数N(N<=30),代表我给你的字符串的个数,然后接下来的就是我要给你的那N个字符串(字符串长度<=10^6)啦。而你要告诉我你的答案的话,只要将你计算出的最长回文子串的长度按照我给你的顺序依次输出到标准输出就可以了!你看这就是一个例子。”

样例输入

3
abababa
aaaabaa
acacdas

样例输出

7
5
3
题目链接:http://hihocoder.com/problemset/problem/1032
解答来源:http://blog.csdn.net/dyx404514/article/details/42061017
代码:
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;

public class Test{
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner in =new  Scanner(System.in);
		//System.out.println("please input num: ");
		int num = in.nextInt();
		//System.out.println(in.next());
		for(int i = 0;i < num; i++){
			//String input = null;
			char[] input = new char[1000001];
			//input = in.next();
			input = in.next().toCharArray();
			char[] data = new char[2*input.length+1];
			
			//System.out.println(data.length);
			for(int k = 0;k < input.length; k++){
				//System.out.println(k);
				data[2*k] = '#';
				data[2*k+1] = input[k];
			}
			data[2*input.length] = '#';
			
			//int po = 0;
			int[] len = new int[data.length];
			for(int k = 0;k < data.length; k++)
				len[k] = 0;
			int max = 1;
			int po = 0;
			len[0] = 1;
			for(int k = 1;k < data.length; k++){
				//System.out.println("cycletimes: "+k);
				if(max>k)		//max包含k的情况
					len[k] = len[po*2-k] < (max-k) ? len[po*2-k] : (max-k);
				else			//max不包含k的情况
					len[k] = 1;
				//System.out.println(len[k]+"  "+data[k-len[k]]+" "+data[k+len[k]]);
				while((k-len[k])>=0&&(k+len[k])<data.length&&data[k-len[k]]==data[k+len[k]]){
					len[k]++;
					//System.out.println("len[k] "+len[k]);
				}
					
				if(len[k]+k>max){
					max = len[k]+k;
					po = k;	
				}
			}
			max = 0;
			for(int k = 0;k < data.length; k++)
				if(max<len[k])
					max = len[k];
			System.out.println((max-1));
			//System.out.println();
			//System.out.println(data);
			
			}
		}
}

  借鉴代码:

#include <bits/stdc++.h>
using namespace std;

int N;
string s;

void solve() {
    string s1;
    s1.resize(2 * s.size() + 2);
    s1[0] = '$';
    s1[1] = '#';
    for (int i = 0; i < s.size(); ++i) {
        s1[(i + 1) << 1] = s[i];
        s1[((i + 1) << 1) + 1] = '#';
    }
    vector<int> p(s1.size(), 0);
    int res = 0;
    for (int id = 0, i = 1; i < s1.size(); ++i) {
        if (p[id] + id > i) p[i] = min(p[2 * id - i], p[id] + id - i);
        else p[i] = 1;
        while (s1[i + p[i]] == s1[i - p[i]]) ++p[i];
        if (i + p[i] > id + p[id]) id = i;
        res = max(res, p[i]);
    }
    cout << res - 1 << endl;
}

int main() {
    cin >> N;
    while (N--) {
        cin >> s;
        solve();
    }
    return 0;
}
态度决定高度,细节决定成败,
原文地址:https://www.cnblogs.com/lxk2010012997/p/4780315.html