# Longest Palindromic Substring using Dynamic Programming

• Difficulty Level : Medium
• Last Updated : 20 Jan, 2023

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

Examples:

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

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

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  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```