Problem Overview
The Shortest Palindrome problem is a common string manipulation challenge, where you’re tasked with transforming a given string into its shortest possible palindrome by adding characters to its front. A palindrome is a string that reads the same backward as forward. The challenge is to efficiently compute the minimal characters required to achieve this, maintaining optimal performance for large strings.
Solution Breakdown
This solution uses the KMP (Knuth-Morris-Pratt) algorithm to solve the problem efficiently. The KMP algorithm is commonly used in string matching problems, and here it helps in identifying the longest prefix of the input string that is also a suffix.
Here’s how the solution works step by step:
- Reverse the Input String:
- The first step is to reverse the input string. This helps in checking how much of the string is already a palindrome and how much more needs to be added.
- Combine the Original and Reversed String:
- Next, we create a new string by concatenating the original string, a special separator character (to avoid overlap), and the reversed string. This combined string is then used to create an LPS (Longest Prefix which is also Suffix) array.
- Build the LPS Array:
- The LPS array helps us identify how much of the string matches both at the start and the end. It essentially tells us how many characters in the suffix match the prefix, thus indicating the length of the palindrome that already exists in the string.
- Add the Missing Characters:
- Once we have the LPS array, we calculate how many characters from the reversed string need to be added to the front to form the shortest palindrome. The result is the substring of the reversed string, combined with the original input string, giving us the shortest possible palindrome.
Code Explanation
Here is the JavaScript implementation of the algorithm:
/**
* @param {string} s
* @return {string}
*/
function shortestPalindrome(s) {
const reverseStr = s.split('').reverse().join(''); // Reverse the input string
const combinedStr = s + '#' + reverseStr; // Combine original and reversed with a separator
const n = combinedStr.length;
// Create the LPS (Longest Prefix which is also Suffix) array for KMP algorithm
const lps = new Array(n).fill(0);
// Build the LPS array for the combined string
for (let i = 1, len = 0; i < n; ) {
if (combinedStr[i] === combinedStr[len]) {
lps[i++] = ++len;
} else if (len > 0) {
len = lps[len - 1];
} else {
i++;
}
}
// The number of characters that are not part of the palindrome
const charsToAdd = s.length - lps[n - 1];
// Add those characters (from the reversed string) to the front
return reverseStr.substring(0, charsToAdd) + s;
}
Time Complexity
- Time Complexity: The time complexity of this solution is O(n) where
n
is the length of the input string. This is due to the efficient construction of the LPS array using the KMP algorithm. - Space Complexity: The space complexity is O(n), which includes space for the LPS array and the combined string.
Conclusion
By leveraging the KMP algorithm, this solution efficiently finds the shortest palindrome by determining the minimal characters needed to prepend to the string. It ensures optimal performance even for large inputs, making it a robust approach to solving the Shortest Palindrome problem.