214. Shortest Palindrome
Difficulty: Hard
Topics: String
, Rolling Hash
, String Matching
, Hash Function
You are given a string s
. You can convert s
to a palindrome1 by adding characters in front of it.
Return the shortest palindrome you can find by performing this transformation.
Example 1:
- Input: s = "aacecaaa"
- Output: "aaacecaaa"
Example 2:
- Input: s = "abcd"
- Output: "dcbabcd"
Constraints:
0 <= s.length <= 5 * 104
-
s
consists of lowercase English letters only.
Solution:
We need to find the shortest palindrome by adding characters in front of a given string. We can approach this by identifying the longest prefix of the string that is already a palindrome. Once we have that, the remaining part can be reversed and added to the front to make the entire string a palindrome.
Approach:
-
Identify the longest palindromic prefix: We want to find the longest prefix of the string
s
that is already a palindrome. - Reverse the non-palindromic suffix: The part of the string that isn't part of the palindromic prefix is reversed and added to the beginning of the string.
- Concatenate the reversed suffix and the original string to form the shortest palindrome.
To do this efficiently, we can use string matching techniques such as the KMP (Knuth-Morris-Pratt) algorithm to find the longest palindromic prefix.
Step-by-Step Solution:
-
Create a new string by appending the reverse of the string
s
tos
itself, separated by a special character'#'
to avoid overlap between the string and its reverse.
Let the new string be s + '#' + reverse(s)
.
Use the KMP partial match table (also known as the LPS array, longest prefix suffix) on this new string to determine the longest prefix of
s
that is also a suffix. This will give us the length of the longest palindromic prefix ins
.Construct the shortest palindrome by adding the necessary characters to the front.
Let's implement this solution in PHP: 214. Shortest Palindrome
<?php
/**
* @param String $s
* @return String
*/
function shortestPalindrome($s) {
...
...
...
/**
* go to ./solution.php
*/
}
/**
* Helper function to compute the KMP (LPS array) for string matching
*
* @param $pattern
* @return array
*/
function computeLPS($pattern) {
...
...
...
/**
* go to ./solution.php
*/
}
// Example 1
$s1 = "aacecaaa";
echo shortestPalindrome($s1) . "\n"; // Output: "aaacecaaa"
// Example 2
$s2 = "abcd";
echo shortestPalindrome($s2) . "\n"; // Output: "dcbabcd"
?>
Explanation:
-
computeLPS Function:
- This function computes the longest prefix which is also a suffix (LPS) for the given string. This helps to identify how much of the string
s
is already a palindrome.
- This function computes the longest prefix which is also a suffix (LPS) for the given string. This helps to identify how much of the string
-
Forming the Combined String:
- We combine the original string
s
with its reverse and separate them by a special character#
. The special character ensures that there is no overlap betweens
andreverse(s)
.
- We combine the original string
-
Using the LPS Array:
- The LPS array tells us the longest prefix in
s
which is also a suffix ofs
. This corresponds to the longest part of the string that is already a palindrome.
- The LPS array tells us the longest prefix in
-
Constructing the Shortest Palindrome:
- We find the portion of the string that isn't part of the longest palindromic prefix and reverse it. Then, we add the reversed part to the front of the original string
s
.
- We find the portion of the string that isn't part of the longest palindromic prefix and reverse it. Then, we add the reversed part to the front of the original string
Time Complexity:
- The time complexity of this solution is O(n), where
n
is the length of the string. This is because we are using the KMP algorithm, which runs in linear time.
Example Walkthrough:
Example 1:
Input: s = "aacecaaa"
- Reverse of
s
:"aaacecaa"
- Combined string:
"aacecaaa#aaacecaa"
- LPS array for the combined string gives the longest palindromic prefix as
"aacecaaa"
.
Since the whole string is already a palindrome, no characters need to be added. So the output is "aaacecaaa"
.
Example 2:
Input: s = "abcd"
- Reverse of
s
:"dcba"
- Combined string:
"abcd#dcba"
- LPS array tells us that the longest palindromic prefix is just
"a"
.
So, we add "dcb"
(reverse of "bcd"
) to the front of s
, resulting in "dcbabcd"
.
Conclusion:
This solution efficiently finds the shortest palindrome by leveraging string matching techniques and the KMP algorithm to identify the longest palindromic prefix. The complexity is linear, making it suitable for large input sizes up to 5 * 10^4
.
Contact Links
If you found this series helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!
If you want more helpful content like this, feel free to follow me:
-
Palindrome A palindrome is a string that reads the same forward and backward. ↩
Top comments (0)