Leetcode5-Longest Palindromic Substring(最长回文字串)

题目

Given a string s ,find the longest palindromic in s .You may assume that maximum length of s is 1000,and there exists one unique longest palindromic substring.

题意

求一个给定字符串S的最长回文串,其中回文串指的是可以从串中间向两边扩展的字符串均相等。

思路

manacher算法:

  1. 由于字符串的长度有可能是奇数也有可能是偶数,所以为了统一处理奇偶情况,需要对字符串进行一个预处理。

    abbaabb -> #a#b#b#a#a#b#b#

  2. 定义一个大小与预处理之后的字符串大小相同的数组,用来保存以该位置的字符为回文中心产生的回文半径

    abcdcb

    以第四个位置字符d为中心的回文半径为2,则res[4] = 4

  3. res[]数组的生成方法:对于当前位置i,求回文半径大小。此时i前面位置的回文半径都已经求出了,回文半径扩展到最右边的位置为C ,回文半径为R

    1: 判断i的对称点j,如果res[j]的回文左边缘在 C 的回文左边缘的右边,即2代表的大括号为j的整个回文在C所代表的回文之中,由于C本身是回文,所以res[i] = res[j];

    2: 如果j的回文超出了C的回文,即1包括的字符串,则此时对应的i的回文串至少包含了C的一部分,剩下的部分需要判断idx2位置与idx1位置的字符串是否相等;然后idx2一直向右,idx1一直向左,直到不相等为止,即得到i的回文半径。若回文半径边缘超出了R,则需要更新C=i,R=i + res[i]。

    3: 如果i没有对称点,则需要则需要将i的前后一一比对,这个可以与2放到一起进行。

代码

package Leetcode;

import java.util.Scanner;

//寻找最长回文串
public class lc5 {
    static Scanner sc = new Scanner(System.in);
    static String s = sc.next();
    static char[] b = s.toCharArray();
    static char a [] = new char[2001];
    static int r[] = new int[2001];
    static int w = 2*s.length()+1;
    public static void main(String[] args) {

        int i;
        for (i = 0;i<s.length();i++){
            a[2*i] = '#';
            a[2*i+1] = b[i];
        }
        a[2*i] = '#';

        r[0] = 1;
        int c = 0,R = r[c];
        for (i = 1;i<w;i++){
            int j = c-(i-c);
            if (j<=c-R){
                r[i] = function(i,1);

            }else{
                if (j-r[j]<c-R){
                    r[i] = c+R-i;
                    r[i] = function(i,r[i]);
                }else
                    r[i]=r[j];
            }
        }
        int max = -1;
        for (i = 0;i<w;i++){
            if (max<r[i])
                max = r[i];
        }
        for (i=0;i<w;i++){
            if (r[i] == max)
                break;
        }
        for (int j=i-r[i]+1;j<i+r[i]-1;j++){
            if (j%2!=0)
                System.out.print(a[j]);
        }
    }
    public static int function(int i,int r){
        while (true){
            if (i+r >=w )
                return r;
            if (i-r<=-1)
                return r;
            if (a[i+r] == a[i-r])
                r++;
            else
                return r;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值