GFG App
Open App
Browser
Continue

Longest Palindromic Subsequence | DP-12

Given a sequence, find the length of the longest palindromic subsequence in it.

As another example, if the given sequence is “BBABCBCAB”, then the output should be 7 as “BABCBAB” is the longest palindromic subsequence in it. “BBBBB” and “BBCBB” are also palindromic subsequences of the given sequence, but not the longest ones.
The naive solution for this problem is to generate all subsequences of the given sequence and find the longest palindromic subsequence. This solution is exponential in terms of time complexity. Let us see how this problem possesses both important properties of a Dynamic Programming (DP) Problem and can efficiently be solved using Dynamic Programming.
1) Optimal Substructure:
Let X[0..n-1] be the input sequence of length n and L(0, n-1) be the length of the longest palindromic subsequence of X[0..n-1].
If last and first characters of X are same, then L(0, n-1) = L(1, n-2) + 2.
Else L(0, n-1) = MAX (L(1, n-1), L(0, n-2)).

Following is a general recursive solution with all cases handled.

```// Every single character is a palindrome of length 1
L(i, i) = 1 for all indexes i in given sequence

// IF first and last characters are not same
If (X[i] != X[j])  L(i, j) =  max{L(i + 1, j),L(i, j - 1)}

// If there are only 2 characters and both are same
Else if (j == i + 1) L(i, j) = 2

// If there are more than two characters, and first and last
// characters are same
Else L(i, j) =  L(i + 1, j - 1) + 2 ```

2) Overlapping Subproblems: Following is a simple recursive implementation of the LPS problem. The implementation simply follows the recursive structure mentioned above.

C++

 `// C++ program of above approach` `#include` `using` `namespace` `std;`   `// A utility function to get max of two integers` `int` `max (``int` `x, ``int` `y) { ``return` `(x > y)? x : y; }`   `// Returns the length of the longest palindromic subsequence in seq` `int` `lps(``char` `*seq, ``int` `i, ``int` `j)` `{` `// Base Case 1: If there is only 1 character` `if` `(i == j)` `    ``return` `1;`   `// Base Case 2: If there are only 2 ` `// characters and both are same` `if` `(seq[i] == seq[j] && i + 1 == j)` `    ``return` `2;`   `// If the first and last characters match` `if` `(seq[i] == seq[j])` `    ``return` `lps (seq, i+1, j-1) + 2;`   `// If the first and last characters do not match` `return` `max( lps(seq, i, j-1), lps(seq, i+1, j) );` `}`   `/* Driver program to test above functions */` `int` `main()` `{` `    ``char` `seq[] = ``"GEEKSFORGEEKS"``;` `    ``int` `n = ``strlen``(seq);` `    ``cout << ``"The length of the LPS is "` `         ``<< lps(seq, 0, n-1);` `    ``return` `0;` `}`   `// This code is contributed` `// by Akanksha Rai`

C

 `// C program of above approach` `#include` `#include`   `// A utility function to get max of two integers` `int` `max (``int` `x, ``int` `y) { ``return` `(x > y)? x : y; }`   `// Returns the length of the longest palindromic subsequence in seq` `int` `lps(``char` `*seq, ``int` `i, ``int` `j)` `{` `   ``// Base Case 1: If there is only 1 character` `   ``if` `(i == j)` `     ``return` `1;`   `   ``// Base Case 2: If there are only 2 characters and both are same` `   ``if` `(seq[i] == seq[j] && i + 1 == j)` `     ``return` `2;`   `   ``// If the first and last characters match` `   ``if` `(seq[i] == seq[j])` `      ``return` `lps (seq, i+1, j-1) + 2;`   `   ``// If the first and last characters do not match` `   ``return` `max( lps(seq, i, j-1), lps(seq, i+1, j) );` `}`   `/* Driver program to test above functions */` `int` `main()` `{` `    ``char` `seq[] = ``"GEEKSFORGEEKS"``;` `    ``int` `n = ``strlen``(seq);` `    ``printf` `(``"The length of the LPS is %d"``, lps(seq, 0, n-1));` `    ``getchar``();` `    ``return` `0;` `}`

Java

 `// Java program of above approach` `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {`   `    ``// A utility function to get max of two integers` `    ``static` `int` `max(``int` `x, ``int` `y) { ``return` `(x > y) ? x : y; }` `    ``// Returns the length of the longest palindromic` `    ``// subsequence in seq`   `    ``static` `int` `lps(``char` `seq[], ``int` `i, ``int` `j)` `    ``{` `        ``// Base Case 1: If there is only 1 character` `        ``if` `(i == j) {` `            ``return` `1``;` `        ``}`   `        ``// Base Case 2: If there are only 2 characters and` `        ``// both are same` `        ``if` `(seq[i] == seq[j] && i + ``1` `== j) {` `            ``return` `2``;` `        ``}`   `        ``// If the first and last characters match` `        ``if` `(seq[i] == seq[j]) {` `            ``return` `lps(seq, i + ``1``, j - ``1``) + ``2``;` `        ``}`   `        ``// If the first and last characters do not match` `        ``return` `max(lps(seq, i, j - ``1``), lps(seq, i + ``1``, j));` `    ``}`   `    ``/* Driver program to test above function */` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``String seq = ``"GEEKSFORGEEKS"``;` `        ``int` `n = seq.length();` `        ``System.out.printf(``"The length of the LPS is %d"``,` `                          ``lps(seq.toCharArray(), ``0``, n - ``1``));` `    ``}` `}`

Python3

 `# Python 3 program of above approach`   `# A utility function to get max ` `# of two integers ` `def` `max``(x, y):` `    ``if``(x > y):` `        ``return` `x` `    ``return` `y` `    `  `# Returns the length of the longest ` `# palindromic subsequence in seq ` `def` `lps(seq, i, j):` `    `  `    ``# Base Case 1: If there is ` `    ``# only 1 character ` `    ``if` `(i ``=``=` `j):` `        ``return` `1`   `    ``# Base Case 2: If there are only 2 ` `    ``# characters and both are same ` `    ``if` `(seq[i] ``=``=` `seq[j] ``and` `i ``+` `1` `=``=` `j):` `        ``return` `2` `    `  `    ``# If the first and last characters match ` `    ``if` `(seq[i] ``=``=` `seq[j]):` `        ``return` `lps(seq, i ``+` `1``, j ``-` `1``) ``+` `2`   `    ``# If the first and last characters` `    ``# do not match ` `    ``return` `max``(lps(seq, i, j ``-` `1``), ` `               ``lps(seq, i ``+` `1``, j))`   `# Driver Code` `if` `__name__ ``=``=` `'__main__'``:` `    ``seq ``=` `"GEEKSFORGEEKS"` `    ``n ``=` `len``(seq)` `    ``print``(``"The length of the LPS is"``, ` `                  ``lps(seq, ``0``, n ``-` `1``))` `    `  `# This code contributed by Rajput-Ji`

C#

 `// C# program of the above approach` `using` `System;` `                    `  `public` `class` `GFG{`   `    ``// A utility function to get max of two integers ` `    ``static` `int` `max(``int` `x, ``int` `y) {` `        ``return` `(x > y) ? x : y;` `    ``}` `    ``// Returns the length of the longest palindromic subsequence in seq ` ` `  `    ``static` `int` `lps(``char` `[]seq, ``int` `i, ``int` `j) {` `    ``// Base Case 1: If there is only 1 character ` `        ``if` `(i == j) {` `            ``return` `1;` `        ``}` ` `  `    ``// Base Case 2: If there are only 2 characters and both are same ` `        ``if` `(seq[i] == seq[j] && i + 1 == j) {` `            ``return` `2;` `        ``}` ` `  `    ``// If the first and last characters match ` `        ``if` `(seq[i] == seq[j]) {` `            ``return` `lps(seq, i + 1, j - 1) + 2;` `        ``}` ` `  `    ``// If the first and last characters do not match ` `        ``return` `max(lps(seq, i, j - 1), lps(seq, i + 1, j));` `    ``}` ` `  ` `  `    ``/* Driver program to test above function */` `    ``public` `static` `void` `Main() {` `        ``String seq = ``"GEEKSFORGEEKS"``;` `        ``int` `n = seq.Length;` `        ``Console.Write(``"The length of the LPS is "``+lps(seq.ToCharArray(), 0, n - 1));` ` `  `    ``}` `}`   `// This code is contributed by Rajput-Ji`

PHP

 ``

Javascript

 ``

Output

`The length of the LPS is 5`

Time complexity: The time complexity of the above algorithm is exponential O(2^n), where ‘n’ is the length of the input sequence.

Space complexity: The space complexity of the above algorithm is O(n^2) as we are using a 2D array to store the subproblems solutions.

Considering the above implementation, the following is a partial recursion tree for a sequence of length 6 with all different characters.

```               L(0, 5)
/        \
/          \
L(1,5)          L(0,4)
/    \            /    \
/      \          /      \
L(2,5)    L(1,4)  L(1,4)  L(0,3)```

In the above partial recursion tree, L(1, 4) is being solved twice. If we draw the complete recursion tree, then we can see that there are many subproblems that are solved again and again. Since the same subproblems are called again, this problem has the Overlapping Subproblems property. So LPS problem has both properties (see this and this) of a dynamic programming problem. Like other typical Dynamic Programming(DP) problems, recomputations of the same subproblems can be avoided by constructing a temporary array L[][] in a bottom-up manner.
3) Dynamic Programming Solution:

C++

 `// A Dynamic Programming based C++ program for LPS problem` `// Returns the length of the longest palindromic subsequence in seq` `#include` `#include`   `// A utility function to get max of two integers` `int` `max (``int` `x, ``int` `y) { ``return` `(x > y)? x : y; }`   `// Returns the length of the longest palindromic subsequence in seq` `int` `lps(``char` `*str)` `{` `   ``int` `n = ``strlen``(str);` `   ``int` `i, j, cl;` `   ``int` `L[n][n];  ``// Create a table to store results of subproblems`     `   ``// Strings of length 1 are palindrome of length 1` `   ``for` `(i = 0; i < n; i++)` `      ``L[i][i] = 1;`   `    ``// Build the table. Note that the lower diagonal values of table are` `    ``// useless and not filled in the process. The values are filled in a` `    ``// manner similar to Matrix Chain Multiplication DP solution (See` `    ``// https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/). cl is length of` `    ``// substring` `    ``for` `(cl=2; cl<=n; cl++)` `    ``{` `        ``for` `(i=0; i

Java

 `// A Dynamic Programming based Java` `// Program for the Egg Dropping Puzzle` `import` `java.io.*;` `import` `java.util.*;`   `class` `LPS {`   `    ``// A utility function to get max of two integers` `    ``static` `int` `max(``int` `x, ``int` `y) { ``return` `(x > y) ? x : y; }`   `    ``// Returns the length of the longest` `    ``// palindromic subsequence in seq` `    ``static` `int` `lps(String seq)` `    ``{` `        ``int` `n = seq.length();` `        ``int` `i, j, cl;` `        ``// Create a table to store results of subproblems` `        ``int` `L[][] = ``new` `int``[n][n];`   `        ``// Strings of length 1 are palindrome of length 1` `        ``for` `(i = ``0``; i < n; i++)` `            ``L[i][i] = ``1``;`   `        ``// Build the table. Note that the lower` `        ``// diagonal values of table are` `        ``// useless and not filled in the process.` `        ``// The values are filled in a manner similar` `        ``//  to Matrix Chain Multiplication DP solution (See` `        ``// https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/).` `        ``// cl is length of substring` `        ``for` `(cl = ``2``; cl <= n; cl++) {` `            ``for` `(i = ``0``; i < n - cl + ``1``; i++) {` `                ``j = i + cl - ``1``;` `                ``if` `(seq.charAt(i) == seq.charAt(j)` `                    ``&& cl == ``2``)` `                    ``L[i][j] = ``2``;` `                ``else` `if` `(seq.charAt(i) == seq.charAt(j))` `                    ``L[i][j] = L[i + ``1``][j - ``1``] + ``2``;` `                ``else` `                    ``L[i][j] = max(L[i][j - ``1``], L[i + ``1``][j]);` `            ``}` `        ``}`   `        ``return` `L[``0``][n - ``1``];` `    ``}`   `    ``/* Driver program to test above functions */` `    ``public` `static` `void` `main(String args[])` `    ``{` `        ``String seq = ``"GEEKSFORGEEKS"``;` `        ``int` `n = seq.length();` `        ``System.out.println(``"The length of the LPS is "` `                           ``+ lps(seq));` `    ``}` `}` `/* This code is contributed by Rajat Mishra */`

Python3

 `# // A Dynamic Programming based Python program for LPS problem` `#  Returns the length of the longest palindromic subsequence in seq`     `#  Returns the length of the longest palindromic subsequence in seq` `def` `lps(``str``):` `    ``n ``=` `len``(``str``)`   `    ``L ``=` `[[``0` `for` `i ``in` `range``(n)]``for` `j ``in` `range``(n)]`   `    ``# Strings of length 1 are palindrome of length 1` `    ``for` `i ``in` `range``(n):` `        ``L[i][i] ``=` `1`  `# Create a table to store results of subproblems`   `    ``#  Build the table. Note that the lower diagonal values of table are` `    ``#  useless and not filled in the process. The values are filled in a` `    ``#  manner similar to Matrix Chain Multiplication DP solution (See` `    ``#  https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/). cl is length of` `    ``#  substring` `    ``for` `cl ``in` `range``(``2``, n``+``1``):` `        ``for` `i ``in` `range``(n``-``cl``+``1``):` `            ``j ``=` `i``+``cl``-``1` `            ``if` `str``[i] ``=``=` `str``[j] ``and` `cl ``=``=` `2``:` `                ``L[i][j] ``=` `2` `            ``elif` `str``[i] ``=``=` `str``[j]:` `                ``L[i][j] ``=` `L[i``+``1``][j``-``1``]``+``2` `            ``else``:` `                ``L[i][j] ``=` `max``(L[i][j``-``1``], L[i``+``1``][j])`   `    ``return` `L[``0``][n``-``1``]`     `#  Driver program to test above functions` `if` `__name__ ``=``=` `"__main__"``:` `    ``seq ``=` `"GEEKSFORGEEKS"` `    ``n ``=` `len``(seq)` `    ``print``(``"The length of the LPS is {}"``.``format``(lps(seq)))`   `# This Code is Contributed By Vivek Maddeshiya`

C#

 `// A Dynamic Programming based C# Program` `// for the Egg Dropping Puzzle` `using` `System;`   `class` `GFG {`   `    ``// A utility function to get max of` `    ``// two integers` `    ``static` `int` `max (``int` `x, ``int` `y) ` `    ``{ ` `        ``return` `(x > y)? x : y;` `    ``}` `    `  `    ``// Returns the length of the longest` `    ``// palindromic subsequence in seq` `    ``static` `int` `lps(``string` `seq)` `    ``{` `    ``int` `n = seq.Length;` `    ``int` `i, j, cl;` `    `  `    ``// Create a table to store results` `    ``// of subproblems` `    ``int` `[,]L = ``new` `int``[n,n];` `    `  `    ``// Strings of length 1 are ` `    ``// palindrome of length 1` `    ``for` `(i = 0; i < n; i++)` `        ``L[i,i] = 1;` `            `  `        ``// Build the table. Note that the ` `        ``// lower diagonal values of table` `        ``// are useless and not filled in` `        ``// the process. The values are ` `        ``// filled in a manner similar to` `        ``// Matrix Chain Multiplication DP` `        ``// solution (See` `        ``// https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/` `        ``// cl is length of substring` `        ``for` `(cl = 2; cl <= n; cl++)` `        ``{` `            ``for` `(i = 0; i < n-cl+1; i++)` `            ``{` `                ``j = i + cl - 1;` `                `  `                ``if` `(seq[i] == seq[j] &&` `                                  ``cl == 2)` `                    ``L[i,j] = 2;` `                ``else` `if` `(seq[i] == seq[j])` `                    ``L[i,j] = L[i+1,j-1] + 2;` `                ``else` `                    ``L[i,j] = ` `                     ``max(L[i,j-1], L[i+1,j]);` `            ``}` `        ``}` `            `  `        ``return` `L[0,n-1];` `    ``}` `        `  `    ``/* Driver program to test above ` `    ``functions */` `    ``public` `static` `void` `Main()` `    ``{` `        ``string` `seq = ``"GEEKSFORGEEKS"``;` `        ``int` `n = seq.Length;` `        ``Console.Write(``"The length of the "` `                  ``+ ``"LPS is "``+ lps(seq));` `    ``}` `}`   `// This code is contributed by nitin mittal.`

PHP

 ` \$y)? \$x : \$y; }`   `// Returns the length of the` `// longest palindromic ` `// subsequence in seq` `function` `lps(``\$str``)` `{` `\$n` `= ``strlen``(``\$str``);` `\$i``; ``\$j``; ``\$cl``;`   `// Create a table to store` `// results of subproblems` `\$L``[][] = ``array``(``array``()); `     `// Strings of length 1 are` `// palindrome of length 1` `for` `(``\$i` `= 0; ``\$i` `< ``\$n``; ``\$i``++)` `    ``\$L``[``\$i``][``\$i``] = 1;`   `    ``// Build the table. Note that ` `    ``// the lower diagonal values ` `    ``// of table are useless and ` `    ``// not filled in the process. ` `    ``// The values are filled in a ` `    ``// manner similar to Matrix ` `    ``// Chain Multiplication DP ` `    ``// solution (See ` `    ``// https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/).` `    ``// cl is length of substring` `    ``for` `(``\$cl` `= 2; ``\$cl` `<= ``\$n``; ``\$cl``++)` `    ``{` `        ``for` `(``\$i` `= 0; ``\$i` `< ``\$n` `- ``\$cl` `+ 1; ``\$i``++)` `        ``{` `            ``\$j` `= ``\$i` `+ ``\$cl` `- 1;` `            ``if` `(``\$str``[``\$i``] == ``\$str``[``\$j``] && ` `                            ``\$cl` `== 2)` `            ``\$L``[``\$i``][``\$j``] = 2;` `            ``else` `if` `(``\$str``[``\$i``] == ``\$str``[``\$j``])` `            ``\$L``[``\$i``][``\$j``] = ``\$L``[``\$i` `+ 1][``\$j` `- 1] + 2;` `            ``else` `            ``\$L``[``\$i``][``\$j``] = max(``\$L``[``\$i``][``\$j` `- 1], ` `                             ``\$L``[``\$i` `+ 1][``\$j``]);` `        ``}` `    ``}`   `    ``return` `\$L``[0][``\$n` `- 1];` `}`   `// Driver Code` `\$seq` `= ``'GEEKSFORGEEKS'``;` `\$n` `= ``strlen``(``\$seq``);` `echo` `"The length of the "` `. ` `      ``"LPS is "``, lps(``\$seq``);`   `// This code is contributed` `// by shiv_bhakt.` `?>`

Javascript

 ``

Output

`The length of the LPS is 5`

Time Complexity: O(n^2), which is much better than the worst-case time complexity of Naive Recursive implementation.
Auxiliary Space: O(n^2),  Creating a table

Using Memoization Technique of Dynamic programming: The idea used here is to reverse the given input string and check the length of the longest common subsequence. That would be the answer for the longest palindromic subsequence.

C++

 `// A Dynamic Programming based C++ program for LPS problem` `// Returns the length of the longest palindromic subsequence` `// in seq` `#include ` `using` `namespace` `std;`   `int` `dp[1001][1001];`   `// Returns the length of the longest palindromic subsequence` `// in seq` `int` `lps(string& s1, string& s2, ``int` `n1, ``int` `n2)` `{` `    ``if` `(n1 == 0 || n2 == 0) {` `        ``return` `0;` `    ``}` `    ``if` `(dp[n1][n2] != -1) {` `        ``return` `dp[n1][n2];` `    ``}` `    ``if` `(s1[n1 - 1] == s2[n2 - 1]) {` `        ``return` `dp[n1][n2] = 1 + lps(s1, s2, n1 - 1, n2 - 1);` `    ``}` `    ``else` `{` `        ``return` `dp[n1][n2] = max(lps(s1, s2, n1 - 1, n2),` `                                ``lps(s1, s2, n1, n2 - 1));` `    ``}` `}`   `/* Driver program to test above functions */` `int` `main()` `{` `    ``string seq = ``"GEEKSFORGEEKS"``;` `    ``int` `n = seq.size();` `    ``dp[n][n];` `    ``memset``(dp, -1, ``sizeof``(dp));` `    ``string s2 = seq;` `    ``reverse(s2.begin(), s2.end());` `    ``cout << ``"The length of the LPS is "` `         ``<< lps(s2, seq, n, n) << endl;` `    ``return` `0;` `}`   `// This code is contributed by Arun Bang`

Java

 `// Java program of above approach` `import` `java.io.*;` `import` `java.util.*;` `class` `GFG {`   `    ``// A utility function to get max of two integers` `    ``static` `int` `max(``int` `x, ``int` `y) { ``return` `(x > y) ? x : y; }`   `    ``// Returns the length of the longest palindromic` `    ``// subsequence in seq` `    ``static` `int` `lps(``char` `seq[], ``int` `i, ``int` `j, ``int` `dp[][])` `    ``{`   `        ``// Base Case 1: If there is only 1 character` `        ``if` `(i == j) {` `            ``return` `dp[i][j] = ``1``;` `        ``}`   `        ``// Base Case 2: If there are only 2 characters and` `        ``// both are same` `        ``if` `(seq[i] == seq[j] && i + ``1` `== j) {` `            ``return` `dp[i][j] = ``2``;` `        ``}` `        ``// Avoid extra call for already calculated subproblems, Just return the saved ans from cache` `          ``if``(dp[i][j] != -``1``){` `          ``return` `dp[i][j];` `        ``}` `        ``// If the first and last characters match` `        ``if` `(seq[i] == seq[j]) {` `            ``return` `dp[i][j] = lps(seq, i + ``1``, j - ``1``, dp) + ``2``;` `        ``}`   `        ``// If the first and last characters do not match` `        ``return` `dp[i][j] = max(lps(seq, i, j - ``1``, dp), lps(seq, i + ``1``, j, dp));` `    ``}`   `    ``/* Driver program to test above function */` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``String seq = ``"GEEKSFORGEEKS"``;` `        ``int` `n = seq.length();` `          ``int` `dp[][] = ``new` `int``[n][n];` `          ``for``(``int``[] arr: dp)` `          ``Arrays.fill(arr, -``1``);` `        ``System.out.printf(``"The length of the LPS is %d"``,` `                          ``lps(seq.toCharArray(), ``0``, n - ``1``, dp));` `    ``}` `}`   `// This code is contributed by gauravrajput1`

Python3

 `# A Dynamic Programming based Python program for LPS problem` `# Returns the length of the longest palindromic subsequence` `# in seq`   `dp ``=` `[[``-``1` `for` `i ``in` `range``(``1001``)]``for` `j ``in` `range``(``1001``)]`   `# Returns the length of the longest palindromic subsequence` `# in seq`     `def` `lps(s1, s2, n1, n2):`   `    ``if` `(n1 ``=``=` `0` `or` `n2 ``=``=` `0``):` `        ``return` `0`   `    ``if` `(dp[n1][n2] !``=` `-``1``):` `        ``return` `dp[n1][n2]`   `    ``if` `(s1[n1 ``-` `1``] ``=``=` `s2[n2 ``-` `1``]):` `        ``dp[n1][n2] ``=` `1` `+` `lps(s1, s2, n1 ``-` `1``, n2 ``-` `1``)` `        ``return` `dp[n1][n2]` `    ``else``:` `        ``dp[n1][n2] ``=` `max``(lps(s1, s2, n1 ``-` `1``, n2), lps(s1, s2, n1, n2 ``-` `1``))` `        ``return` `dp[n1][n2]`   `# Driver program to test above functions`     `seq ``=` `"GEEKSFORGEEKS"` `n ``=` `len``(seq)`   `s2 ``=` `seq` `s2 ``=` `s2[::``-``1``]` `print``(f``"The length of the LPS is {lps(s2, seq, n, n)}"``)`   `# This code is contributed by shinjanpatra`

C#

 `// C# code to implement the approach` `using` `System;` `using` `System.Numerics;` `using` `System.Collections.Generic;`   `public` `class` `GFG {`   `    ``// A utility function to get max of two integers` `    ``static` `int` `max(``int` `x, ``int` `y) { ``return` `(x > y) ? x : y; }`   `    ``// Returns the length of the longest palindromic` `    ``// subsequence in seq` `    ``static` `int` `lps(``char``[] seq, ``int` `i, ``int` `j)` `    ``{`   `        ``// Base Case 1: If there is only 1 character` `        ``if` `(i == j) {` `            ``return` `1;` `        ``}`   `        ``// Base Case 2: If there are only 2 characters and` `        ``// both are same` `        ``if` `(seq[i] == seq[j] && i + 1 == j) {` `            ``return` `2;` `        ``}`   `        ``// If the first and last characters match` `        ``if` `(seq[i] == seq[j]) {` `            ``return` `lps(seq, i + 1, j - 1) + 2;` `        ``}`   `        ``// If the first and last characters do not match` `        ``return` `max(lps(seq, i, j - 1), lps(seq, i + 1, j));` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `Main(``string``[] args)` `    ``{` `        ``string` `seq = ``"GEEKSFORGEEKS"``;` `        ``int` `n = seq.Length;` `        ``Console.Write(``"The length of the LPS is "` `                      ``+ lps(seq.ToCharArray(), 0, n - 1));` `    ``}` `}`   `// This code is contributed by sanjoy_62.`

Javascript

 ``

Output

`The length of the LPS is 5`

Time Complexity: O(n2)
Auxiliary Space: O(n2)

Without reversing of an input string: in the above solution, we first reverse the input string and then pass it to the lps function but if we use string character indexing properly then we have no need to reverse the input string. so this way we did not need the reverse of the string, which means we extra saving O(n) space for which need to store the reverse of the input string.

`reverseOfS[n2-1] = s[n-n2]`

C++

 `// A Dynamic Programming based C++ program for LPS problem Returns the length of the longest palindromic subsequence in seq` `#include ` `using` `namespace` `std;`   `int` `dp[1001][1001];` `int` `n;`   `// Returns the length of the longest palindromic subsequence in seq` `int` `lps(string& s, ``int` `n1, ``int` `n2)` `{` `    ``if` `(n1 == 0 || n2 == 0) {` `        ``return` `0;` `    ``}` `    ``if` `(dp[n1][n2] != -1) {` `        ``return` `dp[n1][n2];` `    ``}` `    ``// here instead of using reverse of s as s2` `    ``// we use s[n-1-n2] which is similar to revOfS[n2-1]` `    ``if` `(s[n1 - 1] == s[n - n2]) {` `        ``return` `dp[n1][n2] = 1 + lps(s, n1 - 1, n2 - 1);` `    ``}` `    ``else` `{` `        ``return` `dp[n1][n2] = max(lps(s, n1 - 1, n2),` `                                ``lps(s, n1, n2 - 1));` `    ``}` `}`   `/* Driver program to test above functions */` `int` `main()` `{` `    ``string s = ``"GEEKSFORGEEKS"``;` `    ``n = s.size();` `    ``dp[n][n];` `    ``memset``(dp, -1, ``sizeof``(dp));` `    ``cout << ``"The length of the LPS is "` `<< lps(s, n, n) << endl;` `    ``return` `0;` `}`

Java

 `// A Dynamic Programming based Java program for LPS problem Returns the length of the longest palindromic subsequence in seq` `public` `class` `LPS {` `    ``static` `int` `dp[][] = ``new` `int``[``1001``][``1001``];`   `    ``// Returns the length of the longest palindromic subsequence in seq` `    ``static` `int` `lps(String s, ``int` `n1, ``int` `n2) {` `        ``if` `(n1 == ``0` `|| n2 == ``0``) {` `            ``return` `0``;` `        ``}` `        ``if` `(dp[n1][n2] != -``1``) {` `            ``return` `dp[n1][n2];` `        ``}` `        ``// here instead of using reverse of s as s2` `        ``// we use s[n-1-n2] which is similar to revOfS[n2-1]` `        ``if` `(s.charAt(n1 - ``1``) == s.charAt(s.length() - n2)) {` `            ``return` `dp[n1][n2] = ``1` `+ lps(s, n1 - ``1``, n2 - ``1``);` `        ``}` `        ``else` `{` `            ``return` `dp[n1][n2] = Math.max(lps(s, n1 - ``1``, n2), lps(s, n1, n2 - ``1``));` `        ``}` `    ``}`   `    ``/* Driver program to test above functions */` `    ``public` `static` `void` `main(String[] args) {` `        ``String s = ``"GEEKSFORGEEKS"``;` `        ``int` `n = s.length();` `        ``// Initialize dp array with -1` `        ``for` `(``int` `i = ``0``; i < dp.length; i++) {` `            ``for` `(``int` `j = ``0``; j < dp[``0``].length; j++) {` `                ``dp[i][j] = -``1``;` `            ``}` `        ``}` `        ``System.out.println(``"The length of the LPS is "` `+ lps(s, n, n));` `    ``}` `}` `// This code contributed by SRJ`

Python3

 `def` `lps(s, n1, n2): ` `      `  `    ``# Base Case 1: If there is only 1 character  ` `    ``if` `(n1 ``=``=` `0` `or` `n2 ``=``=` `0``): ` `        ``return` `0` `  `  `    ``# Check if the values are same  ` `    ``# if same, then its a palindrome  ` `    ``if` `(s[n1 ``-` `1``] ``=``=` `s[n ``-` `n2]): ` `        ``return` `1` `+` `lps(s, n1 ``-` `1``, n2 ``-` `1``) ` `  `  `    ``else``: ` `        ``return` `max``(lps(s, n1 ``-` `1``, n2), lps(s, n1, n2 ``-` `1``)) ` `  `  `# Driver program to test above functions ` `s ``=` `"GEEKSFORGEEKS"` `n ``=` `len``(s) ` `  `  `dp ``=` `[[``-``1` `for` `j ``in` `range``(n ``+` `1``)] ``for` `i ``in` `range``(n ``+` `1``)] ` `  `  `print``(``"The length of the LPS is "` `+` `str``(lps(s, n, n)))`   `# This code is contributed by factworx412`

Javascript

 `function` `lps(s, n1, n2) ` `{     ` `    ``// Base Case 1: If there is only 1 character  ` `    ``if` `(n1 == 0 || n2 == 0) ` `        ``return` `0;` `  `  `    ``// Check if the values are same  ` `    ``// if same, then its a palindrome  ` `    ``if` `(s[n1 - 1] == s[n - n2]) ` `        ``return` `1 + lps(s, n1 - 1, n2 - 1) ;` `  `  `    ``else` `        ``return` `Math.max(lps(s, n1 - 1, n2), lps(s, n1, n2 - 1)) ;` `}` `  `  `// Driver program to test above functions ` `let str = ``"GEEKSFORGEEKS"``;` `let n = str.length; ` `  `  `document.write(``"The length of the LPS is "` `+ lps(str, n, n).toString());`

C#

 `// A Dynamic Programming based C# program for LPS problem Returns the length of the longest palindromic subsequence in seq` `using` `System;` `public` `class` `LPSProgram {` `    ``static` `int``[,] dp;` `    ``static` `int` `n;`   `    ``// Returns the length of the longest palindromic subsequence in seq` `    ``static` `int` `lps(``string` `s, ``int` `n1, ``int` `n2)` `    ``{` `        ``if` `(n1 == 0 || n2 == 0) {` `            ``return` `0;` `        ``}` `        ``if` `(dp[n1,n2] != -1) {` `            ``return` `dp[n1,n2];` `        ``}` `        ``// here instead of using reverse of s as s2` `        ``// we use s[n-1-n2] which is similar to revOfS[n2-1]` `        ``if` `(s[n1 - 1] == s[n - n2]) {` `            ``return` `dp[n1,n2] = 1 + lps(s, n1 - 1, n2 - 1);` `        ``}` `        ``else` `{` `            ``return` `dp[n1,n2] = Math.Max(lps(s, n1 - 1, n2),` `                                         ``lps(s, n1, n2 - 1));` `        ``}` `    ``}`   `    ``/* Driver program to test above functions */` `    ``static` `void` `Main()` `    ``{` `        ``string` `s = ``"GEEKSFORGEEKS"``;` `        ``n = s.Length;` `        ``dp = ``new` `int``[n + 1, n + 1];` `        ``for` `(``int` `i = 0; i <= n; i++) {` `            ``for` `(``int` `j = 0; j <= n; j++) {` `                ``dp[i,j] = -1;` `            ``}` `        ``}` `        ``Console.WriteLine(``"The length of the LPS is "` `+ lps(s, n, n));` `    ``}` `}`

Output

```The length of the LPS is 5
```

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

ANOTHER APPROACH USING TABULATION:

Intuition:

1. We make a the reverse of the string and store in string R.
2. Then we declare a 2-D array of size n^2.
3. we fill the array such that the ans of Longest Palindromic Subsequence is stored at arr[n][n].
4. Following is the logic behind the approach:
•         if(s.charAt(i-1)==r.charAt(j-1)) then we fill the psoition of dp[i][j] as 1+dp[i-1][j-1] as both the characters are same and could contribute to the LPS.
• else we fill  dp[i][j] = Math.max(dp[i][j-1],dp[i-1][j] to fill whats the LPS encountered so far as the characters are not matching.

Implementation:

Java

 `// A Dynamic Programming based Java program for LPS problem` `// Returns the length of the longest palindromic subsequence` `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {` `    ``public` `static` `int` `longestPalinSubseq(String S)` `    ``{` `        ``// code here` `        ``String R` `            ``= ``new` `StringBuilder(S).reverse().toString();`   `        ``int` `dp[][]` `            ``= ``new` `int``[S.length() + ``1``][R.length() + ``1``];`   `        ``for` `(``int` `i = ``1``; i <= S.length(); i++) {` `            ``for` `(``int` `j = ``1``; j <= R.length(); j++) {` `                ``if` `(S.charAt(i - ``1``) == R.charAt(j - ``1``))` `                    ``dp[i][j] = ``1` `+ dp[i - ``1``][j - ``1``];` `                ``else` `                    ``dp[i][j] = Math.max(dp[i][j - ``1``],` `                                        ``dp[i - ``1``][j]);` `            ``}` `        ``}` `        ``return` `dp[S.length()][R.length()];` `    ``}` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``String s = ``"GEEKSFORGEEKS"``;` `        ``System.out.println(``"The length of the LPS is "` `                           ``+ longestPalinSubseq(s));` `    ``}` `}` `// This code is contributed by Raunak Singh`

Output

`The length of the LPS is 5`

Time Complexity : O(n^2)
Space Complexity : O(n^2) ,since we are using a 2-D array.

Print Longest Palindromic Subsequence
Longest palindrome subsequence with O(n) space