最长回文串——manacher算法java实现

来源:互联网 发布:淘宝网店策划书ppt 编辑:程序博客网 时间:2024/06/08 17:03

最长回文串是一个很好玩的话题,给出一个无序的不定长的字符序列,如何知道里面的最长回文串呢?

manacher算法的思想是

1 把偶数、奇数长的字符序列变成奇数长度

2 创建一个与字符串等长的数组,用来记录字符序列相应位置上字符的最长回文半径,半径为1时默认为字符本身。

3 然后以每个字符为中轴遍历字符序列,之后求数组的最大值即为最大的半径,即为最长的回文半径。

最长回文串便迎刃而解了。

package com.lgy;public class Manacher {    public static void main(String[] args) {        String s = "acbahkafojlnavnufnavkvnv";        doManacher(s);    }    public static void doManacher(String s) {        //在字符串两头和质检添加特殊字符转成奇数长度,原理:奇数+奇数+1=奇数,偶数+偶数+1=奇数。        StringBuffer sb = new StringBuffer();        sb.append("#");        for (int i = 0; i < s.length(); i++) {            sb = sb.append(s.substring(i, i + 1)).append("#");        }        s = sb.toString();//以每个字符为轴求最长回文串半径,其中半径=1表示字符本身。        int[] p = new int[s.length()];        int left, right = 0;        for (int i = 0; i < s.length(); i++) {            int len = 1;            for (left = i - 1, right = i + 1; left >= 0 && right <= (2 * i) && right < s.length(); left--, right++) {                if (s.charAt(left) == s.charAt(right)) {                    len = len + 1;                    continue;//如果匹配成功就继续                } else {                    break;//不成功就跳出循环                }            }            p[i] = len;        }//end wai for        //求最大的p[i]值        int pos, maxValuePos = 0;        for (int i = 0; i < p.length - 1; i++) {            pos = i;            for (int j = i + 1; j < p.length; j++) {                if (p[i] < p[j]) {                    pos = j;                    int tep = p[i];                    p[i] = p[pos];                    p[pos] = tep;                }                if (i == 0)                    maxValuePos = pos;            }        }        //求得的回文串一定是奇数长度        int realLen = ((p[0] * 2 - 1) - 1) / 2;//最长回文串的长度,去掉其他字符        System.out.println("最长的回文串长度为:" + realLen);//求最长回文串内容        String huiwen;        StringBuffer realHuiwen = new StringBuffer();        if (realLen == 1) {            System.out.println("最长回文串为:" + s.charAt(maxValuePos));        } else {//              截出来            huiwen = s.substring((maxValuePos + 1 - p[0]), maxValuePos + p[0]);//             去掉辅助字符            for (int j = 0; j < huiwen.length(); j++) {                if (j % 2 != 0)                    realHuiwen = realHuiwen.append(huiwen.charAt(j));            }            System.out.println("最长回文串为:" + realHuiwen.toString());        }    }}


原创粉丝点击