 GeeksforGeeks App
Open App Browser
Continue

# Longest Palindromic Substring using Dynamic Programming

Given a string, find the longest substring which is a palindrome.

Examples:

```Input: Given string :"forgeeksskeegfor",
Output: "geeksskeeg".

Input: Given string :"Geeks",
Output: "ee". ```

## BRUTE APPROACH: (TABULATION METHOD)

Intuition:

1. We create a 2-D array to fill the array with appropriate steps.
2. We fill the matrix using the gap method where we fill the matrix in a diagonal way .
3. At every step ,we check if the substring generated has meet the condition of palindrome or not.
4. At every step, we keep a counter variable to store the max length of the palindrome string achieved so far.
5. Atlast we return the ans.

Implementation:

## Java

 `//Java program to print Longest Palindrome in a String` `import` `java.io.*;` `class` `GFG {``    ``static` `String longestPalin(String s)``    ``{` `        ``int` `count = -``1``;``        ``String ans = ``""``;` `        ``int` `n = s.length();``        ``boolean``[][] dp = ``new` `boolean``[n][n];` `        ``for` `(``int` `g = ``0``; g < n; g++) {``            ``for` `(``int` `i = ``0``, j = g; j < n; i++, j++) {``                ``if` `(g == ``0``) {``                    ``dp[i][j] = ``true``;``                ``}``                ``else` `if` `(g == ``1``) {``                    ``if` `(s.charAt(i) == s.charAt(j)) {``                        ``dp[i][j] = ``true``;``                    ``}``                    ``else` `{``                        ``dp[i][j] = ``false``;``                    ``}``                ``}``                ``else` `{``                    ``if` `(s.charAt(i) == s.charAt(j)``                        ``&& dp[i + ``1``][j - ``1``] == ``true``) {``                        ``dp[i][j] = ``true``;``                    ``}``                    ``else` `{``                        ``dp[i][j] = ``false``;``                    ``}``                ``}` `                ``if` `(dp[i][j] == ``true``                    ``&& count < s.substring(i, j + ``1``)``                                   ``.length()) {``                    ``ans = s.substring(i, j + ``1``);``                    ``count = ans.length();``                ``}``            ``}``        ``}``        ``return` `ans;``    ``}``    ``public` `static` `void` `main(String[] args)``    ``{``        ``String str = ``"forgeeksskeegfor"``;``        ``System.out.println(longestPalin(str));``    ``}``}``// This code is contributed by Raunak Singh`

Output

`geeksskeeg`

Time Complexity:  O(N^2), where N is the length of string
Space Complexity: O(N^2) since have created a 2-D array.

Common mistake: Wrong Approach:

Some people will be tempted to come up with a O(n) time complexity quick solution, which is unfortunately flawed (however can be corrected easily):

(i)Reverse S and store it in S’.
(ii)Find the longest common substring between S and S’  which must also be the longest palindromic substring.

This seemed to work, let’s see some examples below.

For example, S = “caba” then  S’ = “abac”.

The longest common substring between S and S’ is “aba”, which is the answer.

Let’s try another example: S = “abacdfgdcaba” then S’ = “abacdgfdcaba”.

The longest common substring between S and S’ is “abacd”. Clearly, this is not a valid palindrome.

Correct Approach:

We could see that the longest common substring method fails when there exists a reversed copy of a non-palindromic substring in some other part of S. To rectify this, each time we find a longest common substring candidate, we check if the substring’s indices are the same as the reversed substring’s original indices. If it is, then we attempt to update the longest palindrome found so far; if not, we skip this and find the next candidate. This gives us an O(n^2) Dynamic Programming solution which uses O(n^2) space (which could be improved to use O(n) space).

Dynamic programming Approach: Dynamic programming solution is already discussed here in the previous post. The time complexity of the Dynamic Programming based solution is O(n^2) and it requires O(n^2) extra space. We can find the longest palindrome substring( LPS ) in (n^2) time with O(1) extra space.

The algorithm below is very simple and easy to understand. The idea is to Fix a center and expand in both directions for longer palindromes and keep track of the longest palindrome seen so far.

ALGO:

1. Maintain a variable ‘ maxLength = 1 ‘ (for storing LPS length) and ‘ start =0 ‘ (for storing starting index of LPS ).
2. The idea is very simple, we will traverse through the entire string with i=0 to i<(length of string).
1. while traversing, initialize ‘lowand ‘highpointer such that low= i-1 and high= i+1.
2. keep incrementing ‘high’ until str[high]==str[i] .
3. similarly keep decrementing ‘low’ until str[low]==str[i].
4. finally we will keep incrementing ‘high’ and decrementing ‘low’ until str[low]==str[high].
5. calculate length=high-low-1, if length > maxLength then maxLength = length and start = low+1 .
3. Print the LPS and return maxLength.

## C++

 `// A O(n^2) time and O(1) space program to``// find the longest palindromic substring``// easy to understand as compared to previous version.``#include ``using` `namespace` `std;` `// A utility function to print``// a substring str[low..high]``// This function prints the``// longest palindrome substring (LPS)``// of str[]. It also returns the``// length of the longest palindrome``int` `longestPalSubstr(string str)``{``    ``int` `n = str.size(); ``// calculating size of string``    ``if` `(n < 2)``        ``return` `n; ``// if string is empty then size will be 0.``                  ``// if n==1 then, answer will be 1(single``                  ``// character will always palindrome)` `    ``int` `maxLength = 1, start = 0;``    ``int` `low, high;``    ``for` `(``int` `i = 0; i < n; i++) {``        ``low = i - 1;``        ``high = i + 1;``        ``while` `(high < n``               ``&& str[high] == str[i]) ``// increment 'high'``            ``high++;` `        ``while` `(low >= 0``               ``&& str[low] == str[i]) ``// decrement 'low'``            ``low--;` `        ``while` `(low >= 0 && high < n``               ``&& str[low] == str[high]) {``            ``low--;``            ``high++;``        ``}` `        ``int` `length = high - low - 1;``        ``if` `(maxLength < length) {``            ``maxLength = length;``            ``start = low + 1;``        ``}``    ``}` `    ``cout << ``"Longest palindrome substring is: "``;``    ``cout << str.substr(start, maxLength);``    ``return` `maxLength;``}` `// Driver program to test above functions``int` `main()``{``    ``string str = ``"forgeeksskeegfor"``;``    ``cout << ``"\nLength is: "` `<< longestPalSubstr(str)``         ``<< endl;``    ``return` `0;``}`

## C

 `// A O(n^2) time and O(1) space``// program to find the longest``// palindromic substring``#include ``#include ` `// A utility function to print``// a substring str[low..high]``void` `printSubStr(``char``* str, ``int` `low, ``int` `high)``{``    ``for` `(``int` `i = low; i <= high; ++i)``        ``printf``(``"%c"``, str[i]);``}` `// This function prints the longest``// palindrome substring (LPS)``// of str[]. It also returns the``// length of the longest palindrome``int` `longestPalSubstr(``char``* str)``{``    ``int` `n = ``strlen``(str); ``// calculating size of string``    ``if` `(n < 2)``        ``return` `n; ``// if string is empty then size will be 0.``                  ``// if n==1 then, answer will be 1(single``                  ``// character will always palindrome)` `    ``int` `maxLength = 1, start = 0;``    ``int` `low, high;``    ``for` `(``int` `i = 0; i < n; i++) {``        ``low = i - 1;``        ``high = i + 1;``        ``while` `(high < n``               ``&& str[high] == str[i]) ``// increment 'high'``            ``high++;` `        ``while` `(low >= 0``               ``&& str[low] == str[i]) ``// decrement 'low'``            ``low--;` `        ``while` `(low >= 0 && high < n``               ``&& str[low] == str[high]) {``            ``low--; ``// decrement low``            ``high++; ``// increment high``        ``}` `        ``int` `length = high - low - 1;``        ``if` `(maxLength < length) {``            ``maxLength = length;``            ``start = low + 1;``        ``}``    ``}``    ``printf``(``"Longest palindrome substring is: "``);``    ``printSubStr(str, start, start + maxLength - 1);``    ``return` `maxLength;``}` `// Driver program to test above functions``int` `main()``{``    ``char` `str[] = ``"forgeeksskeegfor"``;``    ``printf``(``"\nLength is: %d"``, longestPalSubstr(str));``    ``return` `0;``}`

## Java

 `// Java implementation of O(n^2)``// time and O(1) space method``// to find the longest palindromic substring``public` `class` `LongestPalinSubstring {``  ` `    ``// This function prints the``    ``// longest palindrome substring``    ``// (LPS) of str[]. It also``    ``// returns the length of the``    ``// longest palindrome``    ``static` `int` `longestPalSubstr(String str)``    ``{``        ``int` `n = str.length(); ``// calculating size of string``        ``if` `(n < ``2``)``            ``return` `n; ``// if string is empty then size will be 0.``                  ``// if n==1 then, answer will be 1(single``                  ``// character will always palindrome)` `        ``int` `maxLength = ``1``,start=``0``;``        ``int` `low, high;``        ``for` `(``int` `i = ``0``; i < n; i++) {``            ``low = i - ``1``;``            ``high = i + ``1``;``            ``while` `( high < n && str.charAt(high) == str.charAt(i)) ``//increment 'high'                                  ``                ``high++;``      ` `            ``while` `( low >= ``0` `&& str.charAt(low) == str.charAt(i)) ``// decrement 'low'                   ``                ``low--;``      ` `            ``while` `(low >= ``0` `&& high < n && str.charAt(low) == str.charAt(high) ){``                  ``low--;``                ``high++;``        ``}` `        ``int` `length = high - low - ``1``;``        ``if` `(maxLength < length){``            ``maxLength = length;``            ``start=low+``1``;``        ``}``    ``}   ``    ``System.out.print(``"Longest palindrome substring is: "``);``    ``System.out.println(str.substring(start, start + maxLength ));``    ``return` `maxLength;``      ` ` ``}` `    ``// Driver program to test above function``    ``public` `static` `void` `main(String[] args)``    ``{` `        ``String str = ``"forgeeksskeegfor"``;``        ``System.out.println(``"Length is: "``                           ``+ longestPalSubstr(str));``    ``}``}`

## Python3

 `# A O(n ^ 2) time and O(1) space program to find the``# longest palindromic substring` `# This function prints the longest palindrome substring (LPS)``# of str[]. It also returns the length of the longest palindrome`  `def` `longestPalSubstr(string):``    ``n ``=` `len``(string) ``# calculating size of string``    ``if` `(n < ``2``):``        ``return` `n ``# if string is empty then size will be 0.``                  ``# if n==1 then, answer will be 1(single``                  ``# character will always palindrome)``    ``start``=``0``    ``maxLength ``=` `1``    ``for` `i ``in` `range``(n):``        ``low ``=` `i ``-` `1``        ``high ``=` `i ``+` `1``        ``while` `(high < n ``and` `string[high] ``=``=` `string[i] ):                              ``            ``high``=``high``+``1``      ` `        ``while` `(low >``=` `0` `and` `string[low] ``=``=` `string[i] ):                ``            ``low``=``low``-``1``      ` `        ``while` `(low >``=` `0` `and` `high < n ``and` `string[low] ``=``=` `string[high] ):``          ``low``=``low``-``1``          ``high``=``high``+``1``        ` `    ` `        ``length ``=` `high ``-` `low ``-` `1``        ``if` `(maxLength < length):``            ``maxLength ``=` `length``            ``start``=``low``+``1``            ` `    ``print` `(``"Longest palindrome substring is:"``,end``=``" "``)``    ``print` `(string[start:start ``+` `maxLength])``    ` `    ``return` `maxLength``    ` `# Driver program to test above functions``string ``=` `(``"forgeeksskeegfor"``)``print``(``"Length is: "` `+` `str``(longestPalSubstr(string)))`

## C#

 `// C# implementation of O(n^2) time``// and O(1) space method to find the``// longest palindromic substring``using` `System;` `class` `GFG {` `    ``// This function prints the longest``    ``// palindrome substring (LPS) of str[].``    ``// It also returns the length of the``    ``// longest palindrome``    ``public` `static` `int` `longestPalSubstr(``string` `str)``    ``{``        ``int` `n = str.Length; ``// calculating size of string``        ``if` `(n < 2)``            ``return` `n; ``// if string is empty then size will be 0.``                  ``// if n==1 then, answer will be 1(single``                  ``// character will always palindrome)` `        ``int` `maxLength = 1,start=0;``        ``int` `low, high;``        ``for` `(``int` `i = 0; i < n; i++) {``            ``low = i - 1;``            ``high = i + 1;``            ``while` `( high < n && str[high] == str[i] ) ``//increment 'high'                                  ``                ``high++;``      ` `            ``while` `( low >= 0 && str[low] == str[i]) ``// decrement 'low'                   ``                ``low--;``      ` `            ``while` `(low >= 0 && high < n && str[low] == str[high] ){``                  ``low--;``                ``high++;``        ``}` `        ``int` `length = high - low - 1;``        ``if` `(maxLength < length){``            ``maxLength = length;``            ``start=low+1;``        ``}``    ``}   ``    ``Console.Write(``"Longest palindrome substring is: "``);``    ``Console.WriteLine(str.Substring(start, maxLength));``    ``return` `maxLength;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main(``string``[] args)``    ``{``        ``string` `str = ``"forgeeksskeegfor"``;``        ``Console.WriteLine(``"Length is: "``                          ``+ longestPalSubstr(str));``    ``}``}`

## Javascript

 ``

Output

```Longest palindrome substring is: geeksskeeg
Length is: 10```

Complexity Analysis:

• Time complexity: O(n^2), where n is the length of the input string.
Outer Loop that traverses through the entire string, and Inner Loop that is used to expand from i .
• Auxiliary Space: O(1).
No extra space is needed.

The Above approach is a cleaner way.

The function implementation to print the LPS and return the maxLength is given below:

## C++

 `// A O(n^2) time and O(1) space program to``// find the longest palindromic substring``// easy to understand as compared to previous version.` `#include ``using` `namespace` `std;` `int` `maxLength; ``// variables to store and``string res; ``// update  maxLength and res` `// A utility function to get the longest palindrome``// starting and expanding out from given center indices``void` `cSubUtil(string& s, ``int` `l, ``int` `r)``{``    ``// check if the indices lie in the range of string``    ``// and also if it is palindrome``    ``while` `(l >= 0 && r < s.length() && s[l] == s[r]) {``        ``// expand the boundary``        ``l--;``        ``r++;``    ``}``    ``// if it's length is greater than maxLength update``    ``// maxLength and res``    ``if` `(r - l - 1 >= maxLength) {``        ``res = s.substr(l + 1, r - l - 1);``        ``maxLength = r - l - 1;``    ``}``    ``return``;``}``// A function which takes a string prints the LPS and``// returns the length of LPS``int` `longestPalSubstr(string str)``{``    ``res = ``""``;``    ``maxLength = 1;``    ``// for every index in the string check palindromes``    ``// starting from that index``    ``for` `(``int` `i = 0; i < str.length(); i++) {``        ``// check for odd length palindromes``        ``cSubUtil(str, i, i);``        ``// check for even length palindromes``        ``cSubUtil(str, i, i + 1);``    ``}` `    ``cout << ``"Longest palindrome substring is: "``;``    ``cout << res << ``"\n"``;` `    ``return` `maxLength;``}` `// Driver program to test above functions``int` `main()``{``    ``string str = ``"forgeeksskeegfor"``;``    ``cout << ``"\nLength is: "` `<< longestPalSubstr(str)``         ``<< endl;``    ``return` `0;``}`

## Java

 `// Java implementation of O(n^2)``// time and O(1) space method``// to find the longest palindromic substring` `public` `class` `LongestPalinSubstring {` `    ``static` `int` `maxLength; ``// variables to store and``    ``static` `String res; ``// update  maxLength and res` `    ``// A utility function to get the longest palindrome``    ``// starting and expanding out from given center indices``    ``static` `void` `cSubUtil(String s, ``int` `l, ``int` `r)``    ``{``        ``// check if the indices lie in the range of string``        ``// and also if it is palindrome``        ``while` `(l >= ``0` `&& r < s.length()``               ``&& s.charAt(l) == s.charAt(r)) {``            ``// expand the boundary``            ``l--;``            ``r++;``        ``}``        ``// if it's length is greater than maxLength update``        ``// maxLength and res``        ``if` `(r - l - ``1` `>= maxLength) {``            ``res = s.substring(l + ``1``, r);``            ``maxLength = r - l - ``1``;``        ``}``        ``return``;``    ``}``    ``// A function which takes a string prints the LPS and``    ``// returns the length of LPS``    ``static` `int` `longestPalSubstr(String str)``    ``{``        ``res = ``""``;``        ``maxLength = ``1``;``        ``// for every index in the string check palindromes``        ``// starting from that index``        ``for` `(``int` `i = ``0``; i < str.length(); i++) {``            ``// check for odd length palindromes``            ``cSubUtil(str, i, i);``            ``// check for even length palindromes``            ``cSubUtil(str, i, i + ``1``);``        ``}``        ``System.out.print(``            ``"Longest palindrome substring is: "``);``        ``System.out.println(res);``        ``return` `maxLength;``    ``}` `    ``// Driver program to test above function``    ``public` `static` `void` `main(String[] args)``    ``{` `        ``String str = ``"forgeeksskeegfor"``;``        ``System.out.println(``"Length is: "``                           ``+ longestPalSubstr(str));``    ``}``}`

## Python3

 `# Python 3 implementation of O(n^2)``# time and O(1) space method``# to find the longest palindromic substring``class` `LongestPalinSubstring :``    ``maxLength ``=` `0``    ` `    ``# variables to store and``    ``res ``=` `None``    ` `    ``# update  maxLength and res``    ``# A utility function to get the longest palindrome``    ``# starting and expanding out from given center indices``    ``@staticmethod``    ``def` `cSubUtil( s,  l,  r) :``      ` `        ``# check if the indices lie in the range of string``        ``# and also if it is palindrome``        ``while` `(l >``=` `0` `and` `r < ``len``(s) ``and` `s[l] ``=``=` `s[r]) :``          ` `            ``# expand the boundary``            ``l ``-``=` `1``            ``r ``+``=` `1``            ` `        ``# if it's length is greater than maxLength update``        ``# maxLength and res``        ``if` `(r ``-` `l ``-` `1` `>``=` `LongestPalinSubstring.maxLength) :``            ``LongestPalinSubstring.res ``=` `s[l ``+` `1``:r]``            ``LongestPalinSubstring.maxLength ``=` `r ``-` `l ``-` `1``        ``return``      ` `    ``# A function which takes a string prints the LPS and``    ``# returns the length of LPS``    ``@staticmethod``    ``def`  `longestPalSubstr( ``str``) :``        ``LongestPalinSubstring.res ``=` `""``        ``LongestPalinSubstring.maxLength ``=` `1``        ` `        ``# for every index in the string check palindromes``        ``# starting from that index``        ``i ``=` `0``        ``while` `(i < ``len``(``str``)) :``          ` `            ``# check for odd length palindromes``            ``LongestPalinSubstring.cSubUtil(``str``, i, i)``            ` `            ``# check for even length palindromes``            ``LongestPalinSubstring.cSubUtil(``str``, i, i ``+` `1``)``            ``i ``+``=` `1``        ``print``(``"Longest palindrome substring is: "``, end ``=``"")``        ``print``(LongestPalinSubstring.res)``        ``return` `LongestPalinSubstring.maxLength``      ` `    ``# Driver program to test above function``    ``@staticmethod``    ``def` `main( args) :``        ``str1 ``=` `"forgeeksskeegfor"``        ``print``(``"Length is: "` `+` `str``(LongestPalinSubstring.longestPalSubstr(str1)))``    ` `if` `__name__``=``=``"__main__"``:``    ``LongestPalinSubstring.main([])``    ` `    ``# This code is contributed by phasing17.`

## C#

 `// C# implementation of O(n^2) time``// and O(1) space method to find the``// longest palindromic substring``using` `System;` `class` `GFG {` `    ``static` `int` `maxLength; ``// variables to store and``    ``static` `string` `res; ``// update  maxLength and res` `    ``// A utility function to get the longest palindrome``    ``// starting and expanding out from given center indices``    ``public` `static` `void` `cSubUtil(``string` `s, ``int` `l, ``int` `r)``    ``{``        ``// check if the indices lie in the range of string``        ``// and also if it is palindrome``        ``while` `(l >= 0 && r < s.Length && s[l] == s[r]) {``            ``// expand the boundary``            ``l--;``            ``r++;``        ``}``        ``// if it's length is greater than maxLength update``        ``// maxLength and res``        ``if` `(r - l - 1 >= maxLength) {``            ``res = s.Substring(l + 1, r - l - 1);``            ``maxLength = r - l - 1;``        ``}``        ``return``;``    ``}``    ``// A function which takes a string prints the LPS and``    ``// returns the length of LPS``    ``public` `static` `int` `longestPalSubstr(``string` `str)``    ``{``        ``res = ``""``;``        ``maxLength = 1;``        ``// for every index in the string check palindromes``        ``// starting from that index``        ``for` `(``int` `i = 0; i < str.Length; i++) {``            ``// check for odd length palindromes``            ``cSubUtil(str, i, i);``            ``// check for even length palindromes``            ``cSubUtil(str, i, i + 1);``        ``}` `        ``Console.Write(``"Longest palindrome substring is: "``);``        ``Console.WriteLine(res);``        ``return` `maxLength;``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main(``string``[] args)``    ``{``        ``string` `str = ``"forgeeksskeegfor"``;``        ``Console.WriteLine(``"Length is: "``                          ``+ longestPalSubstr(str));``    ``}``}`

## Javascript

 `// A O(n^2) time and O(1) space program to``// find the longest palindromic substring``// easy to understand as compared to previous version.` `let maxLength = 0; ``// variables to store and``let res = ``""``; ``// update  maxLength and res` `// A utility function to get the longest palindrome``// starting and expanding out from given center indices``function` `cSubUtil(s, l, r) {``    ``// check if the indices lie in the range of string``    ``// and also if it is palindrome``    ``while` `(l >= 0 && r < s.length && s[l] === s[r]) {``        ``// expand the boundary``        ``l--;``        ``r++;``    ``}``    ``// if it's length is greater than maxLength update``    ``// maxLength and res``    ``if` `(r - l - 1 >= maxLength) {``        ``res = s.substring(l + 1, r);``        ``maxLength = r - l - 1;``    ``}``    ``return``;``}``// A function which takes a string prints the LPS and``// returns the length of LPS``function` `longestPalSubstr(str) {``    ``res = ``""``;``    ``maxLength = 1;``    ``// for every index in the string check palindromes``    ``// starting from that index``    ``for` `(let i = 0; i < str.length; i++) {``        ``// check for odd length palindromes``        ``cSubUtil(str, i, i);``        ``// check for even length palindromes``        ``cSubUtil(str, i, i + 1);``    ``}` `    ``console.log(``"Longest palindrome substring is: "` `+ res);` `    ``return` `maxLength;``}` `// Driver program to test above functions``let str = ``"forgeeksskeegfor"``;``console.log(``"\nLength is: "` `+ longestPalSubstr(str));` `// This code is contributed by akashish__`

Output

```Longest palindrome substring is: geeksskeeg

Length is: 10```