Algorithm succinctly - horse-drawn carriage algorithm (Manacher's Algorithm) - find the longest palindrome substring

EDITORIAL

In general when searching the longest substring palindromic, by more extended center solution , this solution is time complexity of O (n ^ 2), the horse-drawn vehicles sophisticated algorithm to the time complexity O (n), is an algorithm person named Manacher proposed in 1975.

1- Pretreatment

Original string '#' separator, the same characters and does not increase in end to end.
E.g:

原始字符串:abba                   -->字符串长度为:4
将字符串以‘#’分离:#a#b#a#b#        -->字符串长度为:9
首尾增加不相同的字符:$#a#b#a#b#^    -->字符串长度为:11

原始字符串:ersds                  -->字符串长度为:5
将字符串以‘#’分离:#e#r#s#d#s#      -->字符串长度为:11
首尾增加不相同的字符:$#e#r#s#d#s#^  -->字符串长度为:13

The string "#" isolated: the length of the string object are converted to an odd number.
And last increase is not the same character: The aim is to stop setting conditions traversal, because ending characters are the same as any other character.

2- calculated longest substring length palindromic

Definition of two containers: arr [], p [] , and a variable I
ARR [] characters in all records, p [] is recorded in the center of each character is the longest radius palindrome

	i	0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18
arr[]	$	#	a	#	b	#	a	#	b	#	c	#	b	#	a	#	e	#	^
 p[]	1	1	2	1	2	1	4	1	2	1	6	1	2	1	2	1	2	1	1

# One more character than the original interval since all have increased the original string '#' symbol, which increases
the number of characters is increased after # 1 minus the number of characters equal to the initial string

Thus, we finally obtain the relationship between the maximum radius and maximum palindrome palindromic substring length: int maxLength = p [i] -1. maxLength represents palindromic longest substring length.

If you do not take a few examples may be appreciated that authentication: int maxLength = p [i] -1

3- calculating the longest substring starting index palindromic

Because separators are increased #, # it will be present in the end positions of the substring palindromic
equal to the number of sides of the palindromic substring of characters and number #

E.g:

当i=5时,此时回文子串为#,回文子串的左侧为:$#a#b
当i=6时,此时回文子串为#b#a#b#,回文子串的左侧为:$#a
	其中:回文子串左侧的字符数量 = 回文子串的左侧长度 / 2

And because the length of the left side may be acquired by palindromic substring ip [i],
then: the number of sub-strings palindromic the left = (ip [i]) / 2
Therefore: palindromic longest substring starting index of int index = (i - p [ i]) / 2.

If you do not take a few examples may be appreciated that authentication: int index = (i - p [i]) / 2.

4- calculation array p

2,3 two steps are used in an array of p, p array is how come it? We also need the other two variables id and MX
id is a palindrome substring center, mx is a palindrome substring rightmost position limit

	i	0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18
arr[]	$	#	a	#	b	#	a	#	b	#	c	#	b	#	a	#	e	#	^
 p[]	1	1	2	1	2	1	4	1	2	1	6	1	2	1	2	1	2	1	1
 
 当i=6时,id=6, mx=10,那么p[id] = mx -id = 4
 当i=7时,id=7, mx=8,那么p[id] = mx -id = 1
 当i=8时,id=8, mx=10,那么p[id] = mx -id = 2

Because palindromic substring is centrally symmetric, known central positions symmetrical id, if a palindromic substring of i as the center, and comprises the palindromic substring in id as the center, i.e. mx> i, then there will certainly be another j is a central palindromic substring, and i is the center in the sub-palindromic strings are equal and symmetrical, i.e., p [j] = p [i], i and j are the id is symmetrical, i.e., i + j = 2id, If you know the value of i, then j = 2id - i.

例如:当id= 6,i = 8 时,
根据:j = 2*id - i,计算得:j = 4.
反之:当id= 6,i = 4 时,计算得:j = 8.

	i	0	1	2	3	4	5	6	7	8	9	10	11	12	13	14	15	16	17	18
arr[]	$	#	a	#	b	#	a	#	b	#	c	#	b	#	a	#	e	#	^
 p[]	1	1	2	1	2	1	4	1	2	1	6	1	2	1	2	1	2	1	1

But we need to consider another case, if there is a palindrome with i-centered substring, still have mx> i, but with i-centered palindrome substring over the right border mx, the i's to this mx back substring in the text, and the other end of the palindromic symmetry to j substrings centered or equal, in which case p [i] = mx - i, p [j] = [pi], as for the child outside the right border sequence mx , i that is centered outside the palindromic substring whether the portion satisfies the above condition or the need to traverse the comparison character.

Thus, in the mx> i, where, p [i] = Math.min ( p [2id - i], mx - i).
Also, if i is greater than the mx, that is, behind the border substring mx, characters still need to compare calculated.

The sample code

public class Test {
    public static void main(String[] args) {
        String nums = "ababcbae";
        String s = longestPalindrome2(nums);
        System.out.println("符合条件的集合为:"+s);
    }
    public static String preProcess(String s) {
        int n = s.length();
        if (n == 0) {
            return "^$";
        }
        String ret = "^";
        for (int i = 0; i < n; i++)
            ret += "#" + s.charAt(i);
        ret += "#$";
        return ret;
    }

    // 马拉车算法
    public static String longestPalindrome2(String s) {
        //预处理字符串
        String str = preProcess(s);
        int n = str.length();
        int[] p = new int[n];
        int id = 0, mx = 0;
        // 最长回文子串的长度
        int maxLength = -1;
        // 最长回文子串的中心位置索引
        int index = 0;
        for (int j=1; j<n-1; j++) {
            p[j] = mx > j ? Math.min(p[2*id-j], mx-j) : 1;
            // 向左右两边延伸,扩展右边界
            while (str.charAt(j+p[j]) == str.charAt(j-p[j])) {
                p[j]++;
            }
            // 如果回文子串的右边界超过了mx,则需要更新mx和id的值
            if (mx < p[j] + j) {
                mx = p[j] + j;
                id = j;
            }
            // 如果回文子串的长度大于maxLength,则更新maxLength和index的值
            if (maxLength < p[j] - 1) {
                maxLength = p[j] - 1;
                index = j;
            }
        }
        // 截取字符串,输出结果
        int start = (index-maxLength)/2;
        return s.substring(start, start + maxLength);
    }
}

operation result

Here Insert Picture Description

Published 17 original articles · won praise 17 · views 3073

Guess you like

Origin blog.csdn.net/weixin_43954926/article/details/104204537