码迷,mamicode.com
首页 > 其他好文 > 详细

Leetcode:Longest Palindromic Substring之详细分析

时间:2015-07-03 10:45:37      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:leetcode   longest palindromic   manacher alogorithm   

原题链接:https://leetcode.com/problems/longest-palindromic-substring/

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

翻译:求给定字符串中最长回文串的长度

方法:Manachers Alogorithm(此算法可达到O(n)时间)

小序:刚开始看这道题大牛的们的解法时,看不懂(原谅我是个渣渣。。。)后来多看了几篇才明白,觉得应该详细记录说明一下

AC代码:

public class Solution {

    public String longestPalindrome(String s) {

        int[] p = new int[2048];//用整型数组来保存trans中以res[i]为中心的回文串长度(单边)

        //将s中各个字符间插入分隔符,以巧妙得忽略s中字符个数的奇偶差异

    StringBuilder trans = new StringBuilder("#");//首尾都加额外字符防溢出(实际循环的范围仍是字符串长度,故不影响)

    for(int i=0; i<s.length(); i++) {

    trans.append("#");

    trans.append(s.charAt(i));

    }

    trans.append("##");

    

    int mx = 0;//保存当前最长回文串的右边界

    int id = 0;//保存当前最长回文串的对称中心所在位置

    int end_extend = 0;//保存最终确定的最长回文子串的长度

    int end_center = 0;//保存最终确定的最长回文子串对称中心在trans中的位置

    

    for(int i=1; i<trans.length()-1; i++) {

    p[i] = mx>i ? Math.min(p[2*id-i], mx-i) : 1;//其中p[2*id-i]是当前位置i关于id对称位置j=2*id-i的p[j].之所以要取二者中较小值是防止当对应p[j]较大时,以i为中心的p[i]会溢出(超过字符串长度)

    while(trans.charAt(i+p[i]) == trans.charAt(i-p[i])) //循环检查以i为中心,左右对称位置的值(p[i]为半径的值)是否相同,相同则证明回文串长度有

    p[i]++;

    

    if(i+p[i] > mx) { //如果当前回文串的右边界已经超过了上个回文串的右边界,

    mx = i + p[i]; //则更新回文串右边界长度为当前回文串右边界长度

    id = i; //同时保存此时的对称中心位置

    }

    

    if(p[i] > end_extend) {

    end_extend = p[i];

    end_center = i;

    }

    }

    

    return s.substring((end_center - end_extend)/2, (end_center -end_extend)/2 + end_extend -1);

    }

}
<span style="color:#000000;BACKGROUND: rgb(255,255,255)"></span>
<span style="font-size:14px;"><span style="BACKGROUND-COLOR: #ffff33"><span style="color:#000000;BACKGROUND-IMAGE: none; BACKGROUND-ATTACHMENT: scroll; BACKGROUND-REPEAT: repeat; BACKGROUND-POSITION: 0% 0%"></span></span></span> 
<span style="font-size:14px;"><span style="BACKGROUND-COLOR: #ffff33"><span style="color:#000000;BACKGROUND-IMAGE: none; BACKGROUND-ATTACHMENT: scroll; BACKGROUND-REPEAT: repeat; BACKGROUND-POSITION: 0% 0%">原理:</span><span style="color:#000000;BACKGROUND-IMAGE: none; BACKGROUND-ATTACHMENT: scroll; BACKGROUND-REPEAT: repeat; BACKGROUND-POSITION: 0% 0%">Manacher</span><span style="color:#000000;BACKGROUND-IMAGE: none; BACKGROUND-ATTACHMENT: scroll; BACKGROUND-REPEAT: repeat; BACKGROUND-POSITION: 0% 0%">’</span><span style="color:#000000;BACKGROUND-IMAGE: none; BACKGROUND-ATTACHMENT: scroll; BACKGROUND-REPEAT: repeat; BACKGROUND-POSITION: 0% 0%">s Alogorithm</span></span></span>

利用一个辅助数组p[i]记录trans[i]为中心的回文子串长度。

(参考自:http://www.cnblogs.com/daoluanxiaozi/p/longest-palindromic-substring.html

Manacher算法的巧妙之处在于:用mx记录之前保存的最长回文子串长度所能达到的最后边界,用id记录其对称中心,从而计算部分从位置id至位置mx之间元素的p[i]时,利用回文子串的对称性,找其关于id对称位置p[2*id - i],二者相等。如下图:

 技术分享

刚才只提到部分,是因为如果p[2*id-i] > mx-i,假设p[i] = p[2*id - i](即假设以i为中心,可以向其右边扩展p[i]个元素,并且有对应i左边的元素与其对称)显然,这并不总是成立

举例说明:

s :cdabadabac

trans: ##c#d#a#b#a#d#a#b#a#c##

具体如图:

技术分享

其实正是p[i] =Math.min(p[2*id-i], mx-i) 的原理

欢迎转载学习~

版权声明:本文为博主原创文章,未经博主允许不得转载。

Leetcode:Longest Palindromic Substring之详细分析

标签:leetcode   longest palindromic   manacher alogorithm   

原文地址:http://blog.csdn.net/yangyao_iphone/article/details/46732667

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!