We use cookies to ensure you have the best browsing experience on our website. Please read our cookie policy for more information about how we use cookies.
- Prepare
- Algorithms
- Strings
- Build a Palindrome
- Discussions
Build a Palindrome
Build a Palindrome
Sort by
recency
|
57 Discussions
|
Please Login in order to post a comment
I looked at the editorial but couldn't follow it. Here's my solution.
Prerequisites: Be able to create a suffix array from a string with LCP, be able to make RMQ queries on the LCP array, and implement Manacher's algorithm to find maximum palindromes.
Given two strings A and B, let revB = rev(B), and A' and B' are two substrings in A and revB where A' == B'. Then the solution will be the maximal length of the string where: A' + (palindrome in A after A') + B' OR B' + (palindrome in revB after B') + A'
We can handle both these cases by reversing B and independently finding the best result for A + rev(B) and rev(B) + A.
Let's solve for A, then we can find the final answer by swapping A and rev(B) and returning the best result.
First, we use Manacher's algorithm to give us an array of the max length of the palindromes starting at each index of a string. Manacher's algorithm gives us the maximal length of the palindrome centered at each index of a modified string of the form "|a|b|c|...|", so we can convert that into an array of the the maximal palindromes starting at the indexes of the original string "abc..." by changing coordinates, then fill in all non-maximal values:
Now we have lp = longest_palindrome_by_start(a).
Then, we compute a suffix array with LCP for "a$rev(b)", and a data structure to compute RMQ over the LCP. A solution palindrome looks like (substring of a) + (palidnrome in a after substring) + (substring of a in rev(b)). We have to find the lexicographically least solution palindrome of maximum length.
The suffix array gives us lexicographically ordered suffixes of the combined string "a$rev(b)". For every index in a, we need the maximum length of the common substring between a[i..] and b. To do that in lexicographical order, we maintain two pointers into the suffix array, left and right, which correspond to elements of the suffix array which are both in B. At each step, every element between left and right are all in A. For any i between left and right, the longest common substring between A and B is lcs = max(rmq[left + 1, i], rmq[i + 1, right]). Using this lcs, we can calculate the suffix_palindrome_len = lp[sa[i] + lcs], and the total palindrome length will be 2 * lcs + suffix_palindrome_len. We just track the max palindrome and return the first one which hits the max length:
Note that we have to do this both for a + rev(b) and rev(b) + a and report out the max by length and lexicographical order.
Java, Brute Force TLE version
c++
any alternative to using LCS table? Because using LCS table for longer inputs, abort gets called. The solution which without table i am thinking is very complicated
Why when combining "bac" and "bac" is the answer not "abcba"?