Open In App

Longest Palindromic Substring using Dynamic Programming

Last Updated : 07 Mar, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given a string s, the task is to find the longest substring which is a palindrome. If there are multiple answers, then return the first occurrence of the longest palindromic substring from left to right.

Examples:

Input: s = “aaaabbaa
Output: “aabbaa”
Explanation: The longest palindromic substring is “aabbaa”.

Input: s = “geeks” 
Output: “ee”

Input: s = “abc” 
Output: “a”

Input: s = “” 
Output: “”

Approach:

The idea is to use Dynamic Programming to store the status of smaller substrings and use these results to check if a longer substring forms a palindrome. If we know the status (i.e., palindrome or not) of the substring ranging [i, j], we can find the status of the substring ranging [i-1, j+1] by only matching the character s[i-1] and s[j+1].

  • If the substring from i to j is not a palindrome, then the substring from i-1 to j+1 will also not be a palindrome. Otherwise, it will be a palindrome only if s[i-1] and s[j+1] are the same.

Based on this fact, we can create a 2D table (say dp[][] which stores status of substring s[i…j] ), and check for substrings with length from 1 to n. For each length find all the substrings starting from each character i and find if it is a palindrome or not using the above idea. The longest length for which a palindrome formed will be the required answer.

Illustration:

Follow the below illustration for a better understanding.

Consider the string “geeks“. Below is the structure of the table formed and from this, we can see that the longest substring is 2.


Step by step approach:

  1. Maintain a boolean dp[n][n] that is filled in a bottom-up manner.
  2. Fill the table initially for substrings of length = 1 and length = 2 (All substrings of length 1 are palindrome and all substrings of length 2 with same characters are also palindrome).
  3. Iterate for all possible lengths from 3 to n:
    • For each length iterate from i = 0 to n-length, find the end of the substring j = i+length-1. To calculate table[i][j], check the value of table[i+1][j-1]:
      • if the value is true and str[i] is the same as str[j], then we make table[i][j] true.
      • Otherwise, the value of table[i][j] is made false.
  4. Update the longest palindrome accordingly whenever a new palindrome of greater length is found.
C++
// C++ program to find the longest
// palindromic substring.
#include <bits/stdc++.h>
using namespace std;

// Function to find the longest palindrome substring
string longestPalindrome(string &s) {
    int n = s.size();
    vector<vector<bool>> dp(n, vector<bool>(n, false));
    
    int start = 0, maxLen = 1;

    // All substrings of length 1 are palindromes
    for (int i = 0; i < n; ++i)
        dp[i][i] = true;

    // Check for sub-string of length 2
    for (int i = 0; i < n - 1; ++i) {
        if (s[i] == s[i + 1]) {
            dp[i][i + 1] = true;
            if (maxLen<2) {
                start = i;
                maxLen = 2;
            }
        }
    }

    // Check for lengths greater than 2
    for (int k = 3; k <= n; ++k) {
        for (int i = 0; i < n - k + 1; ++i) {
            int j = i + k - 1;

            if (dp[i + 1][j - 1] && s[i] == s[j]) {
                dp[i][j] = true;

                if (k > maxLen) {
                    start = i;
                    maxLen = k;
                }
            }
        }
    }

    return s.substr(start, maxLen);
}

int main() {
    string s = "aaaabbaa";
    cout << longestPalindrome(s) << endl;
    return 0;
}
Java
// Java program to find the longest
// palindromic substring.

import java.util.*;

class GfG {

    // Function to find the longest palindrome substring
    static String longestPalindrome(String s) {
        int n = s.length();
        boolean[][] dp = new boolean[n][n];
        
        int start = 0, maxLen = 1;

        // All substrings of length 1 are palindromes
        for (int i = 0; i < n; ++i)
            dp[i][i] = true;

        // Check for sub-string of length 2
        for (int i = 0; i < n - 1; ++i) {
            if (s.charAt(i) == s.charAt(i + 1)) {
                dp[i][i + 1] = true;
                if (maxLen < 2) {
                    start = i;
                    maxLen = 2;
                }
            }
        }

        // Check for lengths greater than 2
        for (int k = 3; k <= n; ++k) {
            for (int i = 0; i < n - k + 1; ++i) {
                int j = i + k - 1;

                if (dp[i + 1][j - 1] && s.charAt(i) == s.charAt(j)) {
                    dp[i][j] = true;

                    if (k > maxLen) {
                        start = i;
                        maxLen = k;
                    }
                }
            }
        }

        return s.substring(start, start + maxLen);
    }

    public static void main(String[] args) {
        String s = "aaaabbaa";
        System.out.println(longestPalindrome(s));
    }
}
Python
# Python program to find the longest
# palindromic substring.

# Function to find the longest palindrome substring
def longestPalindrome(s):
    n = len(s)
    dp = [[False] * n for _ in range(n)]
    
    start, maxLen = 0, 1

    # All substrings of length 1 are palindromes
    for i in range(n):
        dp[i][i] = True

    # Check for sub-string of length 2
    for i in range(n - 1):
        if s[i] == s[i + 1]:
            dp[i][i + 1] = True
            if maxLen < 2:
                start = i
                maxLen = 2

    # Check for lengths greater than 2
    for k in range(3, n + 1):
        for i in range(n - k + 1):
            j = i + k - 1

            if dp[i + 1][j - 1] and s[i] == s[j]:
                dp[i][j] = True

                if k > maxLen:
                    start = i
                    maxLen = k

    return s[start:start + maxLen]

if __name__ == "__main__":
    s = "aaaabbaa"
    print(longestPalindrome(s))
C#
// C# program to find the longest
// palindromic substring.

using System;

class GfG {

    // Function to find the longest palindrome substring
    static string longestPalindrome(string s) {
        int n = s.Length;
        bool[,] dp = new bool[n, n];
        
        int start = 0, maxLen = 1;

        // All substrings of length 1 are palindromes
        for (int i = 0; i < n; ++i)
            dp[i, i] = true;

        // Check for sub-string of length 2
        for (int i = 0; i < n - 1; ++i) {
            if (s[i] == s[i + 1]) {
                dp[i, i + 1] = true;
                if (maxLen < 2) {
                    start = i;
                    maxLen = 2;
                }
            }
        }

        // Check for lengths greater than 2
        for (int k = 3; k <= n; ++k) {
            for (int i = 0; i < n - k + 1; ++i) {
                int j = i + k - 1;

                if (dp[i + 1, j - 1] && s[i] == s[j]) {
                    dp[i, j] = true;

                    if (k > maxLen) {
                        start = i;
                        maxLen = k;
                    }
                }
            }
        }

        return s.Substring(start, maxLen);
    }

    static void Main(string[] args) {
        string s = "aaaabbaa";
        Console.WriteLine(longestPalindrome(s));
    }
}
JavaScript
// JavaScript program to find the longest
// palindromic substring.

// Function to find the longest palindrome substring
function longestPalindrome(s) {
    const n = s.length;
    const dp = Array.from({ length: n }, () => Array(n).fill(false));

    let start = 0, maxLen = 1;

    // All substrings of length 1 are palindromes
    for (let i = 0; i < n; ++i)
        dp[i][i] = true;

    // Check for sub-string of length 2
    for (let i = 0; i < n - 1; ++i) {
        if (s[i] === s[i + 1]) {
            dp[i][i + 1] = true;
            if (maxLen < 2) {
                start = i;
                maxLen = 2;
            }
        }
    }

    // Check for lengths greater than 2
    for (let k = 3; k <= n; ++k) {
        for (let i = 0; i < n - k + 1; ++i) {
            const j = i + k - 1;

            if (dp[i + 1][j - 1] && s[i] === s[j]) {
                dp[i][j] = true;

                if (k > maxLen) {
                    start = i;
                    maxLen = k;
                }
            }
        }
    }

    return s.substring(start, start + maxLen);
}
//Driver code 
const s = "aaaabbaa";
console.log(longestPalindrome(s));

Output
aabbaa

Time Complexity: O(n^2)
Auxiliary Space: O(n^2)

Related Articles:



Next Article

Similar Reads