Open In App

Maximum length palindromic substring for every index such that it starts and ends at that index

Last Updated : 20 May, 2024
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string S, the task for every index of the string is to find the length of the longest palindromic substring that either starts or ends at that index.

Examples:

Input: S = "bababa"
Output: 5 5 3 3 5 5
Explanation:
Longest palindromic substring starting at index 0 is "babab". Therefore, length = 5
Longest palindromic substring starting at index 1 is "ababa". Therefore,  length = 5
Longest palindromic substring ending at index 2 is "bab". Therefore,  length = 3
Longest palindromic substring ending at index 3 is "aba". Therefore,  length = 3
Longest palindromic substring ending at index 4 is "babab". Therefore,  length = 5
Longest palindromic substring ending at index 5 is "ababa". Therefore,  length = 5 

Input: S = "aaa"
Output: 3 2 3
Explanation:
Longest palindromic substring starting at index 0 is "aaa". Therefore, length = 3
Longest palindromic substring starting at index 1 is "ab". Therefore,  length = 2
Longest palindromic substring ending at index 3 is: "aaa". Therefore, length = 3

Approach: The idea to solve this problem is to traverse the string and for each index, check for the longest palindromic substring that can be formed with that index either as the starting index and the ending index of the palindromic substring. Follow the steps below to solve the problem:

  • Initialize an array palLength[] to store the length of the longest palindromic substrings for each index.
  • Traverse the string using a variable i and perform the following operations:
    • Initialize a variable, say maxLength, to store the length of the longest palindromic substring for each index.
    • Consider i to be the ending index of a palindromic substring and find the first index from j over the range [0, i - 1], such that S[j, i] is a palindrome. Update maxLength.
    • Consider i as the starting index of a palindromic substring and find the last index from j over the range [N - 1, i + 1], such that S[i, j] is a palindrome. Update maxLength.
    • Store the maximum length obtained by storing the value of maxLength in palLength[i].
  • After completing the above steps, print the array palLength[] as the result.

Below is the implementation of the above approach:

C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;

// Function to return true if
// S[i...j] is a palindrome
bool isPalindrome(string S, int i, int j)
{

    // Iterate until i < j
    while (i < j) {

        // If unequal character encountered
        if (S[i] != S[j])
            return false;
        i++;
        j--;
    }

    // Otherwise
    return true;
}

// Function to find for every index,
// longest palindromic substrings
// starting or ending at that index
void printLongestPalindrome(string S, int N)
{

    // Stores the maximum palindromic
    // substring length for each index
    int palLength[N];

    // Traverse the string
    for (int i = 0; i < N; i++) {

        // Stores the maximum length
        // of palindromic substring
        int maxlength = 1;

        // Consider that palindromic
        // substring ends at index i
        for (int j = 0; j < i; j++) {

            // If current character is
            // a valid starting index
            if (S[j] == S[i]) {

                // If S[i, j] is palindrome,
                if (isPalindrome(S, j, i)) {

                    // Update the length of
                    // the longest palindrome
                    maxlength = i - j + 1;
                    break;
                }
            }
        }

        // Consider that palindromic
        // substring starts at index i
        for (int j = N - 1; j > i; j--) {

            // If current character is
            // a valid ending index
            if (S[j] == S[i]) {

                // If str[i, j] is palindrome
                if (isPalindrome(S, i, j)) {

                    // Update the length of
                    // the longest palindrome
                    maxlength = max(j - i + 1, maxlength);
                    break;
                }
            }
        }

        // Update length of the longest
        // palindromic substring for index i
        palLength[i] = maxlength;
    }

    // Print the length of the
    // longest palindromic substring
    for (int i = 0; i < N; i++) {
        cout << palLength[i] << " ";
    }
}

// Driver Code
int main()
{
    string S = "bababa";
    int N = S.length();
    printLongestPalindrome(S, N);
    return 0;
}

// This code is contributed by Kingash.
Java
// Java program for the above approach

class GFG {

    // Function to find for every index,
    // longest palindromic substrings
    // starting or ending at that index
    public static void printLongestPalindrome(String S,
                                              int N)
    {
        // Stores the maximum palindromic
        // substring length for each index
        int palLength[] = new int[N];

        // Traverse the string
        for (int i = 0; i < N; i++) {

            // Stores the maximum length
            // of palindromic substring
            int maxlength = 1;

            // Consider that palindromic
            // substring ends at index i
            for (int j = 0; j < i; j++) {

                // If current character is
                // a valid starting index
                if (S.charAt(j) == S.charAt(i)) {

                    // If S[i, j] is palindrome,
                    if (isPalindrome(S, j, i)) {

                        // Update the length of
                        // the longest palindrome
                        maxlength = i - j + 1;
                        break;
                    }
                }
            }

            // Consider that palindromic
            // substring starts at index i
            for (int j = N - 1; j > i; j--) {

                // If current character is
                // a valid ending index
                if (S.charAt(j) == S.charAt(i)) {

                    // If str[i, j] is palindrome
                    if (isPalindrome(S, i, j)) {

                        // Update the length of
                        // the longest palindrome
                        maxlength = Math.max(j - i + 1,
                                             maxlength);
                        break;
                    }
                }
            }

            // Update length of the longest
            // palindromic substring for index i
            palLength[i] = maxlength;
        }

        // Print the length of the
        // longest palindromic substring
        for (int i = 0; i < N; i++) {
            System.out.print(palLength[i] + " ");
        }
    }

    // Function to return true if
    // S[i...j] is a palindrome
    public static boolean isPalindrome(String S, int i,
                                       int j)
    {
        // Iterate until i < j
        while (i < j) {

            // If unequal character encountered
            if (S.charAt(i) != S.charAt(j))
                return false;
            i++;
            j--;
        }

        // Otherwise
        return true;
    }

    // Driver Code
    public static void main(String[] args)
    {
        String S = "bababa";
        int N = S.length();
        printLongestPalindrome(S, N);
    }
}
Python
# Python program for the above approach

# Function to return true if
# S[i...j] is a palindrome


def isPalindrome(S, i, j):
    # Iterate until i < j
    while (i < j):
        # If unequal character encountered
        if (S[i] != S[j]):
            return False
        i += 1
        j -= 1

    # Otherwise
    return True

# Function to find for every index,
# longest palindromic substrings
# starting or ending at that index


def printLongestPalindrome(S, N):
    # Stores the maximum palindromic
    # substring length for each index
    palLength = [0 for i in range(N)]

    # Traverse the string
    for i in range(N):
        # Stores the maximum length
        # of palindromic substring
        maxlength = 1

        # Consider that palindromic
        # substring ends at index i
        for j in range(i):
            # If current character is
            # a valid starting index
            if (S[j] == S[i]):
                # If S[i, j] is palindrome,
                if (isPalindrome(S, j, i)):
                    # Update the length of
                    # the longest palindrome
                    maxlength = i - j + 1
                    break

        # Consider that palindromic
        # substring starts at index i
        j = N-1
        while(j > i):
            # If current character is
            # a valid ending index
            if (S[j] == S[i]):
                # If str[i, j] is palindrome
                if (isPalindrome(S, i, j)):
                    # Update the length of
                    # the longest palindrome
                    maxlength = max(j - i + 1, maxlength)
                    break
            j -= 1

        # Update length of the longest
        # palindromic substring for index i
        palLength[i] = maxlength

    # Print the length of the
    # longest palindromic substring
    for i in range(N):
        print(palLength[i], end=" ")


# Driver Code
if __name__ == '__main__':
    S = "bababa"
    N = len(S)
    printLongestPalindrome(S, N)

    # This code is contributed by SURENDRA_GANGWAR.
C#
// C# program for the above approach
using System;
class GFG {

    // Function to return true if
    // S[i...j] is a palindrome
    static bool isPalindrome(string S, int i, int j)
    {

        // Iterate until i < j
        while (i < j) {

            // If unequal character encountered
            if (S[i] != S[j])
                return false;
            i++;
            j--;
        }

        // Otherwise
        return true;
    }

    // Function to find for every index,
    // longest palindromic substrings
    // starting or ending at that index
    static void printLongestPalindrome(string S, int N)
    {

        // Stores the maximum palindromic
        // substring length for each index
        int[] palLength = new int[N];

        // Traverse the string
        for (int i = 0; i < N; i++) {

            // Stores the maximum length
            // of palindromic substring
            int maxlength = 1;

            // Consider that palindromic
            // substring ends at index i
            for (int j = 0; j < i; j++) {

                // If current character is
                // a valid starting index
                if (S[j] == S[i]) {

                    // If S[i, j] is palindrome,
                    if ((isPalindrome(S, j, i)) != false) {

                        // Update the length of
                        // the longest palindrome
                        maxlength = i - j + 1;
                        break;
                    }
                }
            }

            // Consider that palindromic
            // substring starts at index i
            for (int j = N - 1; j > i; j--) {

                // If current character is
                // a valid ending index
                if (S[j] == S[i]) {

                    // If str[i, j] is palindrome
                    if (isPalindrome(S, i, j)) {

                        // Update the length of
                        // the longest palindrome
                        maxlength = Math.Max(j - i + 1,
                                             maxlength);
                        break;
                    }
                }
            }

            // Update length of the longest
            // palindromic substring for index i
            palLength[i] = maxlength;
        }

        // Print the length of the
        // longest palindromic substring
        for (int i = 0; i < N; i++) {
            Console.Write(palLength[i] + " ");
        }
    }

    // Driver Code
    static public void Main()
    {
        string S = "bababa";
        int N = S.Length;
        printLongestPalindrome(S, N);
    }
}

// This code is contributed by code_hunt.
JavaScript
<script>
      // JavaScript program for the above approach

      // Function to return true if
      // S[i...j] is a palindrome
      function isPalindrome(S, i, j) {
        // Iterate until i < j
        while (i < j) {
          // If unequal character encountered
          if (S[i] !== S[j]) return false;
          i++;
          j--;
        }

        // Otherwise
        return true;
      }

      // Function to find for every index,
      // longest palindromic substrings
      // starting or ending at that index
      function printLongestPalindrome(S, N) {
        // Stores the maximum palindromic
        // substring length for each index
        var palLength = new Array(N);

        // Traverse the string
        for (var i = 0; i < N; i++) {
          // Stores the maximum length
          // of palindromic substring
          var maxlength = 1;

          // Consider that palindromic
          // substring ends at index i
          for (var j = 0; j < i; j++) {
            // If current character is
            // a valid starting index
            if (S[j] === S[i]) {
              // If S[i, j] is palindrome,
              if (isPalindrome(S, j, i) !== false) {
                // Update the length of
                // the longest palindrome
                maxlength = i - j + 1;
                break;
              }
            }
          }

          // Consider that palindromic
          // substring starts at index i
          for (var j = N - 1; j > i; j--) {
            // If current character is
            // a valid ending index
            if (S[j] === S[i]) {
              // If str[i, j] is palindrome
              if (isPalindrome(S, i, j)) {
                // Update the length of
                // the longest palindrome
                maxlength = Math.max(j - i + 1, maxlength);
                break;
              }
            }
          }

          // Update length of the longest
          // palindromic substring for index i
          palLength[i] = maxlength;
        }

        // Print the length of the
        // longest palindromic substring
        for (var i = 0; i < N; i++) {
          document.write(palLength[i] + "&nbsp;&nbsp;");
        }
      }

      // Driver Code
      var S = "bababa";
      var N = S.length;
      printLongestPalindrome(S, N);
    </script>

Output
5 5 3 3 5 5 

Time Complexity: O(N3)
Auxiliary Space: O(1)

Approach using Dynamic Programming

The task requires us to find the maximum length of palindromic substrings that either start or end at every index in a given string, S. We can achieve this by optimizing the detection of palindromic substrings using a dynamic programming approach which significantly reduces time complexity compared to the naive method.

Steps:

  • Construct the dp table where dp[i][j] will be True if S[i] to S[j] is a palindrome.
  • This is initialized by setting all single-character substrings as palindromes (dp[i][i] = True) and checking two-character substrings.
  • Use the properties of palindromes to expand from each character and from each pair of identical characters to find longer palindromes, updating the results for each index appropriately.

Below is the implementation of above approach:

C++
#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector<int>
print_longest_palindromic_substrings(const string& s)
{
    int n = s.length();
    if (n == 0)
        return {};

    // Initialize DP table with false values
    vector<vector<bool> > dp(n, vector<bool>(n, false));
    vector<int> longest(
        n, 1); // Result array initialized with 1

    // Every single character is a palindrome
    for (int i = 0; i < n; ++i) {
        dp[i][i] = true;
    }

    // Check for two-character palindromes
    for (int i = 0; i < n - 1; ++i) {
        if (s[i] == s[i + 1]) {
            dp[i][i + 1] = true;
            longest[i] = 2;
            longest[i + 1] = 2;
        }
    }

    // Check for palindromes longer than 2
    for (int length = 3; length <= n; ++length) {
        for (int i = 0; i <= n - length; ++i) {
            int j = i + length - 1;
            // Expand if the end characters are the same and
            // the middle substring is a palindrome
            if (s[i] == s[j] && dp[i + 1][j - 1]) {
                dp[i][j] = true;
                longest[i] = max(longest[i], j - i + 1);
                longest[j] = max(longest[j], j - i + 1);
            }
        }
    }

    return longest;
}

int main()
{
    string S = "bababa";
    vector<int> result
        = print_longest_palindromic_substrings(S);

    for (int length : result) {
        cout << length << " ";
    }
    cout << endl;

    return 0;
}
Java
import java.util.Arrays;

public class LongestPalindromicSubstrings {

    public static void main(String[] args)
    {
        String S = "bababa";
        int[] result = printLongestPalindromicSubstrings(S);

        // Print the results
        for (int length : result) {
            System.out.print(length + " ");
        }
        System.out.println();
    }

    public static int[] printLongestPalindromicSubstrings(
        String s)
    {
        int n = s.length();
        if (n == 0)
            return new int[0]; // Return an empty array if
                               // the input string is empty

        // Initialize DP table with false values
        boolean[][] dp = new boolean[n][n];
        int[] longest
            = new int[n]; // Result array initialized with 0
        Arrays.fill(longest,
                    1); // Every single character is a
                        // palindrome of length 1

        // Every single character is a palindrome
        for (int i = 0; i < n; ++i) {
            dp[i][i]
                = true; // Single characters are palindromes
        }

        // Check for two-character palindromes
        for (int i = 0; i < n - 1; ++i) {
            if (s.charAt(i) == s.charAt(i + 1)) {
                dp[i][i + 1]
                    = true; // Two consecutive same
                            // characters are palindromes
                longest[i] = 2; // Update the result array
                longest[i + 1] = 2;
            }
        }

        // Check for palindromes longer than 2
        for (int length = 3; length <= n; ++length) {
            for (int i = 0; i <= n - length; ++i) {
                int j = i + length - 1;
                // Expand if the end characters are the same
                // and the middle substring is a palindrome
                if (s.charAt(i) == s.charAt(j)
                    && dp[i + 1][j - 1]) {
                    dp[i][j] = true; // Mark this substring
                                     // as a palindrome
                    longest[i] = Math.max(
                        longest[i],
                        j - i
                            + 1); // Update the result array
                    longest[j]
                        = Math.max(longest[j], j - i + 1);
                }
            }
        }

        return longest;
    }
}
Python
def print_longest_palindromic_substrings(s):
    n = len(s)
    if n == 0:
        return []

    # Initialize DP table
    dp = [[False] * n for _ in range(n)]
    longest = [1] * n  # Result array

    # Every single character is a palindrome
    for i in range(n):
        dp[i][i] = True

    # Check for two-character palindromes
    for i in range(n - 1):
        if s[i] == s[i + 1]:
            dp[i][i + 1] = True
            longest[i] = 2
            longest[i + 1] = 2

    # Check for palindromes longer than 2
    for length in range(3, n + 1):  # length of the palindrome
        for i in range(n - length + 1):
            j = i + length - 1
            # Expand if the end characters are the same and the middle substring is
            # a palindrome
            if s[i] == s[j] and dp[i + 1][j - 1]:
                dp[i][j] = True
                longest[i] = max(longest[i], j - i + 1)
                longest[j] = max(longest[j], j - i + 1)

    return longest


# Example Usage
S = "bababa"
print(print_longest_palindromic_substrings(S))
JavaScript
function printLongestPalindromicSubstrings(s) {
    const n = s.length;
    if (n === 0) return []; // Return an empty array if the input string is empty

    // Initialize DP table with false values
    const dp = Array.from({ length: n }, () => Array(n).fill(false));
    const longest = new Array(n).fill(1); // Result array initialized with 0

    // Every single character is a palindrome
    for (let i = 0; i < n; ++i) {
        dp[i][i] = true; // Single characters are palindromes
    }

    // Check for two-character palindromes
    for (let i = 0; i < n - 1; ++i) {
        if (s[i] === s[i + 1]) {
            dp[i][i + 1] = true; // Two consecutive same characters are palindromes
            longest[i] = 2; // Update the result array
            longest[i + 1] = 2;
        }
    }

    // Check for palindromes longer than 2
    for (let length = 3; length <= n; ++length) {
        for (let i = 0; i <= n - length; ++i) {
            const j = i + length - 1;
            // Expand if the end characters are the same and the middle substring is a palindrome
            if (s[i] === s[j] && dp[i + 1][j - 1]) {
                dp[i][j] = true; // Mark this substring as a palindrome
                longest[i] = Math.max(longest[i], j - i + 1); // Update the result array
                longest[j] = Math.max(longest[j], j - i + 1);
            }
        }
    }

    return longest;
}

// Example usage
const S = "bababa";
const result = printLongestPalindromicSubstrings(S);

// Print the results
console.log(result.join(" "));

Output
[5, 5, 3, 3, 5, 5]

Time Complexity: O(N^2), where N is the length of the string. The time complexity comes from the need to fill out the DP table which checks all substrings.

Auxilary Space: O(N^2), required for the DP table that holds palindrome information for substrings.


Next Article
Article Tags :
Practice Tags :

Similar Reads