Manacher's algorithm (algorithm to find longest palindrome substring in linear time)

前端 未结 10 487
走了就别回头了
走了就别回头了 2020-12-22 16:02

After spending about 6-8 hours trying to digest the Manacher\'s algorithm, I am ready to throw in the towel. But before I do, here is one last shot in the dark: can anyone e

10条回答
  •  时光说笑
    2020-12-22 16:16

    The Algorithm on this site seems understandable to the certain point http://www.akalin.cx/longest-palindrome-linear-time

    To understand this particular approach the best is to try to solving the problem on paper and catching the tricks you can implement to avoid checking for the palindrome for each possible center.

    First answer yourself - when you find a palindrome of a given length, let's say 5 - can't you as a next step just jump to the end of this palindrome (skipping 4 letters and 4 mid-letters)?

    If you try to create a palindrome with length 8 and place another palindrome with length > 8, which center is in the right side of the first palindrome you will notice something funny. Try it out: Palindrome with length 8 - WOWILIKEEKIL - Like + ekiL = 8 Now in most cases you would be able to write down the place between two E's as a center and number 8 as the length and jump after the last L to look for the center of the bigger palindrome.

    This approach is not correct, which the center of bigger palindrome can be inside ekiL and you would miss it if you would jump after the last L.

    After you find LIKE+EKIL you place 8 in the array that these algos use and this looks like:

    [0,1,0,3,0,1,0,1,0,3,0,1,0,1,0,1,8]

    for

    [#,W,#,O,#,W,#,I,#,L,#,I,#,K,#,E,#]

    The trick is that you already know that most probably next 7 (8-1) numbers after 8 will be the same as on the left side, so the next step is to automatically copy 7 numbers from left of 8 to right of 8 keeping in mind they are not yet final. The array would look like this

    [0,1,0,3,0,1,0,1,0,3,0,1,0,1,0,1,8,1,0,1,0,1,0,3] (we are at 8)

    for

    [#,W,#,O,#,W,#,I,#,L,#,I,#,K,#,E,#,E,#,K,#,I,#,L]

    Let's make an example, that such jump would destroy our current solution and see what we can notice.

    WOWILIKEEKIL - lets try to make bigger palindrome with the center somewhere within EKIL. But its not possible - we need to change word EKIL to something that contain palindrome. What? OOOOOh - thats the trick. The only possibility to have a bigger palindrome with the center in the right side of our current palindrome is that it is already in the right (and left) side of palindrome.

    Let's try to build one based on WOWILIKEEKIL We would need to change EKIL to for example EKIK with I as a center of the bigger palindrome - remember to change LIKE to KIKE as well. First letters of our tricky palindrome will be:

    WOWIKIKEEKIK

    as said before - let the last I be the center of the bigger pallindrome than KIKEEKIK:

    WOWIKIKEEKIKEEKIKIW

    let's make the array up to our old pallindrom and find out how to laverage the additional info.

    for

    [_ W _ O _ W _ I _ K _ I _ K _ E _ E _ K _ I _ K _ E _ E _ K _ I _ K _ I _ W ]

    it will be [0,1,0,3,0,1,0,1,0,3,0,3,0,1,0,1,8

    we know that the next I - a 3rd will be the longest pallindrome, but let's forget about it for a bit. lets copy the numbers in the array from the left of 8 to the right (8 numbers)

    [0,1,0,3,0,1,0,1,0,3,0,3,0,1,0,1,8,1,0,1,0,3,0,3]

    In our loop we are at between E's with number 8. What is special about I (future middle of biggest pallindrome) that we cannot jump right to K (the last letter of currently biggest pallindrome)? The special thing is that it exceeds the current size of the array ... how? If you move 3 spaces to the right of 3 - you are out of array. It means that it can be the middle of the biggest pallindrome and the furthest you can jump is this letter I.

    Sorry for the length of this answer - I wanted to explain the algorythm and can assure you - @OmnipotentEntity was right - I understand it even better after explaining to you :)

提交回复
热议问题