CSES Solution – Longest Palindrome
Last Updated :
26 Mar, 2024
Prerequisite: Manacher’s Algorithm
Given a string, your task is to determine the longest palindromic substring of the string. For example, the longest palindrome in aybabtu is bab.
Example:
Input: s = aybabtu
Output: bab
Input: GeeksgfgGeeks
Output: gfg
Approach:
The idea is to use Manacher’s algorithm, which is a linear time complexity algorithm for finding the longest palindromic substring in a given string.
Lets break down the intuition into some steps:
- We’ll use two arrays, oddLength[] and evenLength[], to store the lengths of the longest odd-length and even-length palindromic substrings centered at each index of the input string.
- Odd-Length Palindromes: First calculates the longest odd-length palindromic substring centered at each index. It uses a variable length to keep track of the current length of the palindrome. It starts from the center and expands in both directions (left and right) until it finds a mismatch or reaches the boundary of the string. The left and right variables are used to keep track of the boundaries of the current longest palindrome.
- Even-Length Palindromes: The process is repeated for even-length palindromes. The only difference is that the initial length is set to 0 and the expansion starts from one position to the left of the center.
- Finding the Longest Palindrome: After the lengths of all palindromic substrings are calculated, iterates over the oddLength and evenLength arrays to find the maximum length and the center of the longest palindromic substring.
- Finally, the longest palindromic substring is extracted from the input string using the substr function and returned.
Steps-by-step approach:
- Two arrays oddLength[] and evenLength[] are declared to store the lengths of the longest palindromic substrings centered at each index.
- Implement solve() function:
- Iterates through the string to find the longest palindromic substring using Manacher’s algorithm.
- For each index i, it calculates the length of the longest odd-length palindromic substring centered at that index.
- Then calculates the length of the longest even-length palindromic substring centered at each index.
- Updates the lengths of palindromic substrings in the oddLength and evenLength arrays.
- Returns the longest palindromic substring found in the input string
Below are the implementation of the above approach:
C++
#include <iostream>
#include <string>
using namespace std;
// Arrays to store the lengths of the longest palindromic
// substrings centered at each index
int oddLength[1000005], evenLength[1000005];
// Function to find the longest palindromic substring
string solve(string& s, int n)
{
// Find the lengths of the longest odd-length
// palindromic substrings centered at each index
for (int i = 0, left = 0, right = -1; i < n; i++) {
// Initialize the length as 1 if the current index
// is beyond the right boundary
int length = (i > right)
? 1
: min(oddLength[left + right - i],
right - i + 1);
// Expand around the center to find the longest
// palindrome
while (0 <= i - length && i + length < n
&& s[i - length] == s[i + length]) {
length++;
}
// Update the length of the longest odd-length
// palindrome centered at index i
oddLength[i] = length--;
// Update the boundaries of the current palindrome
if (i + length > right) {
left = i - length;
right = i + length;
}
}
// Find the lengths of the longest even-length
// palindromic substrings centered at each index
for (int i = 0, left = 0, right = -1; i < n; i++) {
// Initialize the length as 0 if the current index
// is beyond the right boundary
int length
= (i > right)
? 0
: min(evenLength[left + right - i + 1],
right - i + 1);
// Expand around the center to find the longest
// palindrome
while (0 <= i - length - 1 && i + length < n
&& s[i - length - 1] == s[i + length]) {
length++;
}
// Update the length of the longest even-length
// palindrome centered at index i
evenLength[i] = length--;
// Update the boundaries of the current palindrome
if (i + length > right) {
left = i - length - 1;
right = i + length;
}
}
// Find the longest palindromic substring
int maxLength = 0, center = -1;
for (int i = 0; i < n; i++) {
// Update the maxLength and center if a longer
// palindrome is found
if (oddLength[i] * 2 - 1 > maxLength) {
maxLength = oddLength[i] * 2 - 1;
center = i;
}
if (evenLength[i] * 2 > maxLength) {
maxLength = evenLength[i] * 2;
center = i;
}
}
// Return the longest palindromic substring
if (maxLength % 2 == 1)
return s.substr(center - maxLength / 2, maxLength);
return s.substr(center - maxLength / 2, maxLength);
}
// Main function
int main()
{
// Input string
string s = "GeeksgfgGeeks";
int n = s.size();
// Call the solve function and print the result
cout << solve(s, n);
return 0;
}
Java
/* code by flutterfly */
import java.util.Arrays;
public class Main {
// Arrays to store the lengths of the longest palindromic
// substrings centered at each index
static int[] oddLength;
static int[] evenLength;
// Function to find the longest palindromic substring
static String solve(String s, int n) {
oddLength = new int[n];
evenLength = new int[n];
// Find the lengths of the longest odd-length
// palindromic substrings centered at each index
for (int i = 0, left = 0, right = -1; i < n; i++) {
// Initialize the length as 1 if the current index
// is beyond the right boundary
int length = (i > right)
? 1
: Math.min(oddLength[left + right - i], right - i + 1);
// Expand around the center to find the longest
// palindrome
while (0 <= i - length && i + length < n && s.charAt(i - length) == s.charAt(i + length)) {
length++;
}
// Update the length of the longest odd-length
// palindrome centered at index i
oddLength[i] = length--;
// Update the boundaries of the current palindrome
if (i + length > right) {
left = i - length;
right = i + length;
}
}
// Find the lengths of the longest even-length
// palindromic substrings centered at each index
for (int i = 0, left = 0, right = -1; i < n; i++) {
// Initialize the length as 0 if the current index
// is beyond the right boundary
int length = (i > right)
? 0
: Math.min(evenLength[left + right - i + 1], right - i + 1);
// Expand around the center to find the longest
// palindrome
while (0 <= i - length - 1 && i + length < n && s.charAt(i - length - 1) == s.charAt(i + length)) {
length++;
}
// Update the length of the longest even-length
// palindrome centered at index i
evenLength[i] = length--;
// Update the boundaries of the current palindrome
if (i + length > right) {
left = i - length - 1;
right = i + length;
}
}
// Find the longest palindromic substring
int maxLength = 0, center = -1;
for (int i = 0; i < n; i++) {
// Update the maxLength and center if a longer
// palindrome is found
if (oddLength[i] * 2 - 1 > maxLength) {
maxLength = oddLength[i] * 2 - 1;
center = i;
}
if (evenLength[i] * 2 > maxLength) {
maxLength = evenLength[i] * 2;
center = i;
}
}
// Return the longest palindromic substring
if (maxLength % 2 == 1)
return s.substring(center - maxLength / 2, center + maxLength / 2 + 1);
return s.substring(center - maxLength / 2, center + maxLength / 2);
}
// Main function
public static void main(String[] args) {
// Input string
String s = "GeeksgfgGeeks";
int n = s.length();
// Call the solve function and print the result
System.out.println(solve(s, n));
}
}
C#
//code by flutterfly
using System;
class Program
{
// Arrays to store the lengths of the longest palindromic
// substrings centered at each index
static int[] oddLength = new int[1000005];
static int[] evenLength = new int[1000005];
// Function to find the longest palindromic substring
static string Solve(string s, int n)
{
// Find the lengths of the longest odd-length
// palindromic substrings centered at each index
for (int i = 0, left = 0, right = -1; i < n; i++)
{
// Initialize the length as 1 if the current index
// is beyond the right boundary
int length = (i > right) ? 1 : Math.Min(oddLength[left + right - i], right - i + 1);
// Expand around the center to find the longest
// palindrome
while (0 <= i - length && i + length < n && s[i - length] == s[i + length])
{
length++;
}
// Update the length of the longest odd-length
// palindrome centered at index i
oddLength[i] = length--;
// Update the boundaries of the current palindrome
if (i + length > right)
{
left = i - length;
right = i + length;
}
}
// Find the lengths of the longest even-length
// palindromic substrings centered at each index
for (int i = 0, left = 0, right = -1; i < n; i++)
{
// Initialize the length as 0 if the current index
// is beyond the right boundary
int length = (i > right) ? 0 : Math.Min(evenLength[left + right - i + 1], right - i + 1);
// Expand around the center to find the longest
// palindrome
while (0 <= i - length - 1 && i + length < n && s[i - length - 1] == s[i + length])
{
length++;
}
// Update the length of the longest even-length
// palindrome centered at index i
evenLength[i] = length--;
// Update the boundaries of the current palindrome
if (i + length > right)
{
left = i - length - 1;
right = i + length;
}
}
// Find the longest palindromic substring
int maxLength = 0, center = -1;
for (int i = 0; i < n; i++)
{
// Update the maxLength and center if a longer
// palindrome is found
if (oddLength[i] * 2 - 1 > maxLength)
{
maxLength = oddLength[i] * 2 - 1;
center = i;
}
if (evenLength[i] * 2 > maxLength)
{
maxLength = evenLength[i] * 2;
center = i;
}
}
// Return the longest palindromic substring
if (maxLength % 2 == 1)
return s.Substring(center - maxLength / 2, maxLength);
return s.Substring(center - maxLength / 2, maxLength);
}
// Main function
static void Main(string[] args)
{
// Input string
string s = "GeeksgfgGeeks";
int n = s.Length;
// Call the solve function and print the result
Console.WriteLine(Solve(s, n));
}
}
JavaScript
// Arrays to store the lengths of the longest palindromic
// substrings centered at each index
let oddLength = new Array(1000005).fill(0);
let evenLength = new Array(1000005).fill(0);
// Function to find the longest palindromic substring
function solve(s) {
let n = s.length;
// Find the lengths of the longest odd-length
// palindromic substrings centered at each index
for (let i = 0, left = 0, right = -1; i < n; i++) {
// Initialize the length as 1 if the current index
// is beyond the right boundary
let length = (i > right) ? 1 : Math.min(oddLength[left + right - i], right - i + 1);
// Expand around the center to find the longest
// palindrome
while (i - length >= 0 && i + length < n && s[i - length] === s[i + length]) {
length++;
}
// Update the length of the longest odd-length
// palindrome centered at index i
oddLength[i] = length--;
// Update the boundaries of the current palindrome
if (i + length > right) {
left = i - length;
right = i + length;
}
}
// Find the lengths of the longest even-length
// palindromic substrings centered at each index
for (let i = 0, left = 0, right = -1; i < n; i++) {
// Initialize the length as 0 if the current index
// is beyond the right boundary
let length = (i > right) ? 0 : Math.min(evenLength[left + right - i + 1], right - i + 1);
// Expand around the center to find the longest
// palindrome
while (i - length - 1 >= 0 && i + length < n && s[i - length - 1] === s[i + length]) {
length++;
}
// Update the length of the longest even-length
// palindrome centered at index i
evenLength[i] = length--;
// Update the boundaries of the current palindrome
if (i + length > right) {
left = i - length - 1;
right = i + length;
}
}
// Find the longest palindromic substring
let maxLength = 0, center = -1;
for (let i = 0; i < n; i++) {
// Update the maxLength and center if a longer
// palindrome is found
if (oddLength[i] * 2 - 1 > maxLength) {
maxLength = oddLength[i] * 2 - 1;
center = i;
}
if (evenLength[i] * 2 > maxLength) {
maxLength = evenLength[i] * 2;
center = i;
}
}
// Return the longest palindromic substring
if (maxLength % 2 === 1)
return s.substr(center - Math.floor(maxLength / 2), maxLength);
return s.substr(center - Math.floor(maxLength / 2), maxLength);
}
// Main function
function main() {
// Input string
let s = "GeeksgfgGeeks";
// Call the solve function and print the result
console.log(solve(s));
}
// Call the main function
main();
Python3
def solve(s: str, n: int) -> str:
# Arrays to store the lengths of the longest palindromic
# substrings centered at each index
odd_length = [0] * 1000005
even_length = [0] * 1000005
# Function to find the longest palindromic substring
# Find the lengths of the longest odd-length
# palindromic substrings centered at each index
for i in range(n):
left, right = 0, -1
# Initialize the length as 1 if the current index
# is beyond the right boundary
length = 1 if i > right else min(odd_length[left + right - i], right - i + 1)
# Expand around the center to find the longest
# palindrome
while 0 <= i - length and i + length < n and s[i - length] == s[i + length]:
length += 1
# Update the length of the longest odd-length
# palindrome centered at index i
odd_length[i] = length
length -= 1
# Update the boundaries of the current palindrome
if i + length > right:
left, right = i - length, i + length
# Find the lengths of the longest even-length
# palindromic substrings centered at each index
for i in range(n):
left, right = 0, -1
# Initialize the length as 0 if the current index
# is beyond the right boundary
length = 0 if i > right else min(even_length[left + right - i + 1], right - i + 1)
# Expand around the center to find the longest
# palindrome
while 0 <= i - length - 1 and i + length < n and s[i - length - 1] == s[i + length]:
length += 1
# Update the length of the longest even-length
# palindrome centered at index i
even_length[i] = length
length -= 1
# Update the boundaries of the current palindrome
if i + length > right:
left, right = i - length - 1, i + length
# Find the longest palindromic substring
max_length, center = 0, -1
for i in range(n):
# Update the maxLength and center if a longer
# palindrome is found
if odd_length[i] * 2 - 1 > max_length:
max_length = odd_length[i] * 2 - 1
center = i
if even_length[i] * 2 > max_length:
max_length = even_length[i] * 2
center = i
# Return the longest palindromic substring
if max_length % 2 == 1:
return s[center - max_length // 2:center + max_length // 2 + 1]
return s[center - max_length // 2:center + max_length // 2 + 1]
# Input string
s = "GeeksgfgGeeks"
n = len(s)
# Call the solve function and print the result
print(solve(s, n))
Time Complexity: O(n), where n is the length of given string
Auxiliary Space: O(n)
Share your thoughts in the comments
Please Login to comment...