Longest Palindromic Substring using Dynamic Programming (original) (raw)
Last Updated : 23 Jul, 2025
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:
- Maintain a boolean **dp[n][n] that is filled in a bottom-up manner.
- 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).
- 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.
- 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]:
- 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> dp(n, vector(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));
`
**Time Complexity: O(n^2)
**Auxiliary Space: O(n^2)
**Related Articles: