Given a sequence, find the length of the longest palindromic subsequence in it. Examples:
Input : abbaab Output : 4 Input : neveropen Output : 5
We have discussed a Dynamic Programming solution for Longest Palindromic Subsequence which is based on below recursive formula.
// 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
The solution discussed above takes O(n2) extra space. In this post a space optimized solution is discussed that requires O(n) extra space. The idea is to create a one dimensional array a[] of same size as given string. We make sure that a[i] stores length of longest palindromic subsequence of prefix ending with i (or substring s[0..i]).Â
C++
// A Space optimized Dynamic Programming based C++ // program for LPS problem #include <bits/stdc++.h> using namespace std;   // Returns the length of the longest palindromic // subsequence in str int lps(string &s) {     int n = s.length();       // a[i] is going to store length of longest     // palindromic subsequence of substring s[0..i]     int a[n];       // Pick starting point     for ( int i = n - 1; i >= 0; i--) {           int back_up = 0;                     // Pick ending points and see if s[i]         // increases length of longest common         // subsequence ending with s[j].         for ( int j = i; j < n; j++) {               // similar to 2D array L[i][j] == 1             // i.e., handling substrings of length             // one.             if (j == i)                 a[j] = 1;               // Similar to 2D array L[i][j] = L[i+1][j-1]+2             // i.e., handling case when corner characters             // are same.             else if (s[i] == s[j])             {                                   // value a[j] is depend upon previous                 // unupdated value of a[j-1] but in                 // previous loop value of a[j-1] is                 // changed. To store the unupdated                 // value of a[j-1] back_up variable                 // is used.                 int temp = a[j];                 a[j] = back_up + 2;                 back_up = temp;             }               // similar to 2D array L[i][j] = max(L[i][j-1],             // a[i+1][j])             else             {                 back_up = a[j];                 a[j] = max(a[j - 1], a[j]);             }         }     }           return a[n - 1]; }   /* Driver program to test above functions */ int main() {     string str = "GEEKSFORGEEKS" ;     cout << lps(str);     return 0; } |
Java
// A Space optimized Dynamic Programming // based Java program for LPS problem   class GFG {       // Returns the length of the longest     // palindromic subsequence in str     static int lps(String s)     {         int n = s.length();       // a[i] is going to store length     // of longest palindromic subsequence     // of substring s[0..i]         int a[] = new int [n];           // Pick starting point         for ( int i = n - 1 ; i >= 0 ; i--)             {             int back_up = 0 ;       // Pick ending points and see if s[i]     // increases length of longest common     // subsequence ending with s[j].     for ( int j = i; j < n; j++) {       // similar to 2D array L[i][j] == 1     // i.e., handling substrings of length     // one.         if (j == i)         a[j] = 1 ;       // Similar to 2D array L[i][j] = L[i+1][j-1]+2     // i.e., handling case when corner characters     // are same.     else if (s.charAt(i) == s.charAt(j))         {         int temp = a[j];         a[j] = back_up + 2 ;         back_up = temp;         }       // similar to 2D array L[i][j] = max(L[i][j-1],     // a[i+1][j])       else                {                 back_up = a[j];                 a[j] = Math.max(a[j - 1 ], a[j]);             }           }     }     return a[n - 1 ];     }   /* Driver program to test above functions */     public static void main(String[] args)     {         String str = "GEEKSFORGEEKS" ;         System.out.println(lps(str));     } }   //This article is contributed by prerna saini. |
Python3
# A Space optimized Dynamic Programming # based Python3 program for LPS problem   # Returns the length of the longest # palindromic subsequence in str def lps(s):           n = len (s)       # a[i] is going to store length     # of longest palindromic subsequence     # of substring s[0..i]     a = [ 0 ] * n       # Pick starting point     for i in range (n - 1 , - 1 , - 1 ):           back_up = 0       # Pick ending points and see if s[i]     # increases length of longest common     # subsequence ending with s[j].         for j in range (i, n):       # similar to 2D array L[i][j] == 1     # i.e., handling substrings of length     # one.             if j = = i:                 a[j] = 1        # Similar to 2D array L[i][j] = L[i+1][j-1]+2     # i.e., handling case when corner characters     # are same.             elif s[i] = = s[j]:                 temp = a[j]                 a[j] = back_up + 2                 back_up = temp       # similar to 2D array L[i][j] = max(L[i][j-1],     # a[i+1][j])             else :                 back_up = a[j]                 a[j] = max (a[j - 1 ], a[j])       return a[n - 1 ]     # Driver Code string = "GEEKSFORGEEKS" print (lps(string))     # This code is contributed by Ansu Kumari. |
C#
// A Space optimized Dynamic Programming // based C# program for LPS problem using System;   class GFG {       // Returns the length of the longest     // palindromic subsequence in str     static int lps( string s)     {         int n = s.Length;       // a[i] is going to store length     // of longest palindromic subsequence     // of substring s[0..i]         int []a = new int [n];           // Pick starting point         for ( int i = n - 1; i >= 0; i--)             {             int back_up = 0;       // Pick ending points and see if s[i]     // increases length of longest common     // subsequence ending with s[j].     for ( int j = i; j < n; j++) {       // similar to 2D array L[i][j] == 1     // i.e., handling substrings of length     // one.         if (j == i)         a[j] = 1;       // Similar to 2D array L[i][j] = L[i+1][j-1]+2     // i.e., handling case when corner characters     // are same.     else if (s[i] == s[j])         {         int temp = a[j];         a[j] = back_up + 2;         back_up = temp;         }       // similar to 2D array L[i][j] = max(L[i][j-1],     // a[i+1][j])     else             {                 back_up = a[j];                 a[j] = Math.Max(a[j - 1], a[j]);             }         }     }     return a[n - 1];     }       // Driver program     public static void Main()     {         string str = "GEEKSFORGEEKS" ;         Console.WriteLine(lps(str));     } }   // This code is contributed by vt_m. |
PHP
<?php // A Space optimized Dynamic // Programming based PHP // program for LPS problem   // Returns the length of // the longest palindromic . // subsequence in str function lps( $s ) {     $n = strlen ( $s );       // Pick starting point     for ( $i = $n - 1;          $i >= 0; $i --)     {         $back_up = 0;                   // Pick ending points and         // see if s[i] increases         // length of longest common         // subsequence ending with s[j].         for ( $j = $i ; $j < $n ; $j ++)         {               // similar to 2D array             // L[i][j] == 1 i.e.,             // handling substrings             // of length one.             if ( $j == $i )                 $a [ $j ] = 1;               // Similar to 2D array             // L[i][j] = L[i+1][j-1]+2             // i.e., handling case when             // corner characters are same.             else if ( $s [ $i ] == $s [ $j ])             {                                   // value a[j] is depend                 // upon previous unupdated                 // value of a[j-1] but in                 // previous loop value of                 // a[j-1] is changed. To                 // store the unupdated value                 // of a[j-1] back_up variable                 // is used.                 $temp = $a [ $j ];                 $a [ $j ] = $back_up + 2;                 $back_up = $temp ;             }               // similar to 2D array             // L[i][j] = max(L[i][j-1],             // a[i+1][j])             else             {                 $back_up = $a [ $j ];                 $a [ $j ] = max( $a [ $j - 1],                              $a [ $j ]);             }         }     }           return $a [ $n - 1]; }   // Driver Code $str = "GEEKSFORGEEKS" ; echo lps( $str );   // This code is contributed // by shiv_bhakt. ?> |
Javascript
<script>   // A Space optimized Dynamic Programming // based Python3 program for LPS problem   // Returns the length of the longest // palindromic subsequence in str function lps(s){           let n = s.length       // a[i] is going to store length     // of longest palindromic subsequence     // of substring s[0..i]     let a = new Array(n).fill(0);       // Pick starting point     for (let i = n - 1; i >= 0; i--){           let back_up = 0       // Pick ending points and see if s[i]     // increases length of longest common     // subsequence ending with s[j].         for (let j = i; j < n; j++){       // similar to 2D array L[i][j] == 1     // i.e., handling substrings of length     // one.             if (j == i)                 a[j] = 1       // Similar to 2D array L[i][j] = L[i+1][j-1]+2     // i.e., handling case when corner characters     // are same.             else if (s[i] == s[j]){                 let temp = a[j]                 a[j] = back_up + 2                 back_up = temp             }       // similar to 2D array L[i][j] = max(L[i][j-1],     // a[i+1][j])             else {                 back_up = a[j]                 a[j] = Math.max(a[j - 1], a[j])             }         }     }       return a[n - 1] }   // Driver Code let string = "GEEKSFORGEEKS" document.write(lps(string), "</br>" )   // This code is contributed by shinjanpatra   </script> |
5
Time Complexity : O(n*n) Auxiliary Space : O(n)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!