Leetcode:Longest Palindromic Substring之详细分析

原题链接: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.

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

方法:Manacher’s 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) 的原理

欢迎转载学习~

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

时间: 2024-08-24 00:13:31

Leetcode:Longest Palindromic Substring之详细分析的相关文章

LeetCode &quot;Longest Palindromic Substring&quot; - 1D DP

2D DP is an intuitive solution of course, but I got an MLE error, so I simplified it into a 1D DP: class Solution { public: void goDp(vector<int> &dp, int &maxLen, int &is, int &ie, int startLen, int len, string &s) { for(int ile

[LeetCode] Longest Palindromic Substring [14]

题目 Given a string S, find the longest palindromic substring in S. You may assume that the maximum length ofS is 1000, and there exists one unique longest palindromic substring. 原题链接 解题思路 最长回文字串,相信做过Palindrome Partitioning II 这个题的同学应该可以很快做出来.没错,这个题还可以

Leetcode: Longest Palindromic Substring. java

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. 动态规划public class Solution { public String longestPalindrome(String s) { if

[Leetcode] 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. 做这道题之前要先了解什么是回文子串.回文串通俗的解释是,分别从字符串两端开始遍历,得到的结果相同,如"abba",从两端的遍历结果都是:&q

[leetcode]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. 基本思想: 本题的navie解法是对每个(i,j) i<=j 测试是否是回文串,并记录最大的情况.O(n^3) 如果从回文串的中心考虑往两

LeetCode——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. 给定一个字符串S,找出当中的最长回文字符子串. 1.枚举全部子串,并推断是否是回文串同一时候记录最大长度.超时. //找出全部子串,并推断是否是回文串

[LeetCode] 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. http://fisherlei.blogspot.com/2012/12/leetcode-longest-palindromic-substrin

leetcode longest palindromic substring (medium) /java

最长回文字串 上题: 测试用例中,注意aaabaaaa. 但是我time limit exceeded.用了极暴力的方法解.(三层循环)找每一个字符的最长回文字串. 1 /** 2 * 最长回文子串 3 * 2017-5-7 4 **/ 5 6 import java.io.*; 7 import java.util.*; 8 import java.lang.*; 9 10 public class Solution 11 { 12 public static String longestPa

leetcode Longest Palindromic Substring python

class Solution(object): def longestPalindrome(self, s): """ :type s: str :rtype: str """ lenStr = len(s) if lenStr <= 0: return 0 maxLen = 0 tmpLen = 0 tmpRes = '' for i in range(0,lenStr): #odd numbers j=0 tmpLen=0 while