Open In App

Print Longest Palindromic Subsequence

Last Updated : 20 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a sequence, print a longest palindromic subsequence of it. 

Examples : 

Input : BBABCBCAB
Output : BABCBAB
The above output is the longest
palindromic subsequence of given
sequence. "BBBBB" and "BBCBB" are 
also palindromic subsequences of
the given sequence, but not the 
longest ones.

Input : GEEKSFORGEEKS
Output : Output can be either EEKEE
         or EESEE or EEGEE, ..

We have discussed a solution in below post to find length of longest palindromic subsequence. 
Dynamic Programming | Set 12 (Longest Palindromic Subsequence)

Method 1:

This problem is close to the Longest Common Subsequence (LCS) problem. In fact, we can use LCS as a subroutine to solve this problem. Following is the two step solution that uses LCS. 

  1. Reverse the given sequence and store the reverse in another array say rev[0..n-1] 
  2. LCS of the given sequence and rev[] will be the longest palindromic sequence. 
  3. Once we have found LCS, we can print the LCS.

Below is the implementation of above approach:

C++




/* CPP program to print longest palindromic
   subsequence */
#include<bits/stdc++.h>
using namespace std;
 
/* Returns LCS X and Y */
string lcs(string &X, string &Y)
{
    int m = X.length();
    int n = Y.length();
 
    int L[m+1][n+1];
 
    /* Following steps build L[m+1][n+1] in bottom
       up fashion. Note that L[i][j] contains
       length of LCS of X[0..i-1] and Y[0..j-1] */
    for (int i=0; i<=m; i++)
    {
        for (int j=0; j<=n; j++)
        {
            if (i == 0 || j == 0)
                L[i][j] = 0;
            else if (X[i-1] == Y[j-1])
                L[i][j] = L[i-1][j-1] + 1;
            else
                L[i][j] = max(L[i-1][j], L[i][j-1]);
        }
    }
 
    // Following code is used to print LCS
    int index = L[m][n];
 
    // Create a string length index+1 and
    // fill it with \0
    string lcs(index+1, '\0');
 
    // Start from the right-most-bottom-most
    // corner and one by one store characters
    // in lcs[]
    int i = m, j = n;
    while (i > 0 && j > 0)
    {
        // If current character in X[] and Y
        // are same, then current character
        // is part of LCS
        if (X[i-1] == Y[j-1])
        {
            // Put current character in result
            lcs[index-1] = X[i-1];
            i--;
            j--;
 
            // reduce values of i, j and index
            index--;
        }
 
        // If not same, then find the larger of
        // two and go in the direction of larger
        // value
        else if (L[i-1][j] > L[i][j-1])
            i--;
        else
            j--;
    }
 
    return lcs;
}
 
// Returns longest palindromic subsequence
// of str
string longestPalSubseq(string &str)
{
    // Find reverse of str
    string rev = str;
    reverse(rev.begin(), rev.end());
 
    // Return LCS of str and its reverse
    return lcs(str, rev);
}
 
/* Driver program to test above function */
int main()
{
    string str = "GEEKSFORGEEKS";
    cout << longestPalSubseq(str);
    return 0;
}


Java




// Java program to print longest palindromic
// subsequence
import java.io.*;
class GFG {
 
    /* Returns LCS X and Y */
    static String lcs(String a, String b)
    {
        int m = a.length();
        int n = b.length();
        char X[] = a.toCharArray();
        char Y[] = b.toCharArray();
 
        int L[][] = new int[m + 1][n + 1];
 
        /* Following steps build L[m+1][n+1] in bottom
    up fashion. Note that L[i][j] contains
    length of LCS of X[0..i-1] and Y[0..j-1] */
        for (int i = 0; i <= m; i++) {
            for (int j = 0; j <= n; j++) {
                if (i == 0 || j == 0) {
                    L[i][j] = 0;
                }
                else if (X[i - 1] == Y[j - 1]) {
                    L[i][j] = L[i - 1][j - 1] + 1;
                }
                else {
                    L[i][j] = Math.max(L[i - 1][j],
                                       L[i][j - 1]);
                }
            }
        }
 
        // Following code is used to print LCS
        int index = L[m][n];
 
        // Create a String length index+1 and
        // fill it with \0
        char[] lcs = new char[index + 1];
 
        // Start from the right-most-bottom-most
        // corner and one by one store characters
        // in lcs[]
        int i = m, j = n;
        while (i > 0 && j > 0) {
            // If current character in X[] and Y
            // are same, then current character
            // is part of LCS
            if (X[i - 1] == Y[j - 1]) {
                // Put current character in result
                lcs[index - 1] = X[i - 1];
                i--;
                j--;
 
                // reduce values of i, j and index
                index--;
            } // If not same, then find the larger of
            // two and go in the direction of larger
            // value
            else if (L[i - 1][j] > L[i][j - 1]) {
                i--;
            }
            else {
                j--;
            }
        }
        String ans = "";
        for (int x = 0; x < lcs.length; x++) {
            ans += lcs[x];
        }
        return ans;
    }
 
    // Returns longest palindromic subsequence
    // of str
    static String longestPalSubseq(String str)
    {
        // Find reverse of str
        String rev = str;
        rev = reverse(rev);
 
        // Return LCS of str and its reverse
        return lcs(str, rev);
    }
 
    static String reverse(String str)
    {
        String ans = "";
        // convert String to character array
        // by using toCharArray
        char[] try1 = str.toCharArray();
 
        for (int i = try1.length - 1; i >= 0; i--) {
            ans += try1[i];
        }
        return ans;
    }
 
    /* Driver program to test above function */
    public static void main(String[] args)
    {
        String str = "GEEKSFORGEEKS";
        System.out.println(longestPalSubseq(str));
    }
}


Python3




# Python3 program to print longest
# palindromic subsequence
 
# Returns LCS X and Y
def lcs_(X, Y) :
     
    m = len(X)
    n = len(Y)
 
    L = [[0] * (n + 1)] * (m + 1)
 
    # Following steps build L[m+1][n+1]
    # in bottom up fashion. Note that
    # L[i][j] contains length of LCS of
    # X[0..i-1] and Y[0..j-1]
    for i in range(n + 1) :
     
        for j in range(n + 1) :
     
            if (i == 0 or j == 0) :
                L[i][j] = 0;
            elif (X[i - 1] == Y[j - 1]) :
                L[i][j] = L[i - 1][j - 1] + 1;
            else :
                L[i][j] = max(L[i - 1][j],
                              L[i][j - 1]);
     
    # Following code is used to print LCS
    index = L[m][n];
 
    # Create a string length index+1 and
    # fill it with \0
    lcs = ["\n "] * (index + 1)
 
    # Start from the right-most-bottom-most
    # corner and one by one store characters
    # in lcs[]
    i, j= m, n
     
    while (i > 0 and j > 0) :
     
        # If current character in X[] and Y
        # are same, then current character
        # is part of LCS
        if (X[i - 1] == Y[j - 1]) :
         
            # Put current character in result
            lcs[index - 1] = X[i - 1]
            i -= 1
            j -= 1
 
            # reduce values of i, j and index
            index -= 1
         
        # If not same, then find the larger of
        # two and go in the direction of larger
        # value
        elif(L[i - 1][j] > L[i][j - 1]) :
            i -= 1
             
        else :
            j -= 1
     
    ans = ""
     
    for x in range(len(lcs)) :
        ans += lcs[x]
     
    return ans
 
# Returns longest palindromic
# subsequence of str
def longestPalSubseq(string) :
     
    # Find reverse of str
    rev = string[: : -1]
     
    # Return LCS of str and its reverse
    return lcs_(string, rev)
 
# Driver Code
if __name__ == "__main__" :
 
    string = "GEEKSFORGEEKS";
    print(longestPalSubseq(string))
 
# This code is contributed by Ryuga


C#




// C# program to print longest palindromic
//subsequence
using System;
 
public class GFG {
  
    /* Returns LCS X and Y */
    static String lcs(String a, String b) {
        int m = a.Length;
        int n = b.Length;
        char []X = a.ToCharArray();
        char []Y = b.ToCharArray();
  
        int [,]L = new int[m + 1,n + 1];
         int i, j;
        /* Following steps build L[m+1,n+1] in bottom
    up fashion. Note that L[i,j] contains
    length of LCS of X[0..i-1] and Y[0..j-1] */
        for (i = 0; i <= m; i++) {
            for (j = 0; j <= n; j++) {
                if (i == 0 || j == 0) {
                    L[i,j] = 0;
                } else if (X[i - 1] == Y[j - 1]) {
                    L[i,j] = L[i - 1,j - 1] + 1;
                } else {
                    L[i,j] = Math.Max(L[i - 1,j], L[i,j - 1]);
                }
            }
        }
  
        // Following code is used to print LCS
        int index = L[m,n];
  
        // Create a String length index+1 and
        // fill it with \0
        char[] lcs = new char[index + 1];
  
        // Start from the right-most-bottom-most
        // corner and one by one store characters
        // in lcs[]
        i = m; j = n;
        while (i > 0 && j > 0) {
            // If current character in X[] and Y
            // are same, then current character
            // is part of LCS
            if (X[i - 1] == Y[j - 1]) {
                // Put current character in result
                lcs[index - 1] = X[i - 1];
                i--;
                j--;
  
                // reduce values of i, j and index
                index--;
            } // If not same, then find the larger of
            // two and go in the direction of larger
            // value
            else if (L[i - 1,j] > L[i,j - 1]) {
                i--;
            } else {
                j--;
            }
        }
        String ans = "";
        for (int x = 0; x < lcs.Length; x++) {
            ans += lcs[x];
        }
        return ans;
    }
  
// Returns longest palindromic subsequence
// of str
    static String longestPalSubseq(String str) {
        // Find reverse of str
        String rev = str;
        rev = reverse(rev);
  
        // Return LCS of str and its reverse
        return lcs(str, rev);
    }
  
    static String reverse(String str) {
        String ans = "";
        // convert String to character array
        // by using toCharArray
        char[] try1 = str.ToCharArray();
  
        for (int i = try1.Length - 1; i >= 0; i--) {
            ans += try1[i];
        }
        return ans;
    }
  
    /* Driver program to test above function */
    public static void Main() {
        String str = "GEEKSFORGEEKS";
        Console.Write(longestPalSubseq(str));
  
    }
}
// This code is contributed by 29AjayKumar


Javascript




<script>
    // Javascript program to print longest palindromic subsequence
     
    /* Returns LCS X and Y */
    function lcs(a, b) {
        let m = a.length;
        let n = b.length;
        let X = a.split('');
        let Y = b.split('');
   
        let L = new Array(m + 1);
        for (let i = 0; i <= m; i++) {
            L[i] = new Array(n + 1);
            for (let j = 0; j <= n; j++) {
                L[i][j] = 0;
            }
        }
   
        /* Following steps build L[m+1][n+1] in bottom
    up fashion. Note that L[i][j] contains
    length of LCS of X[0..i-1] and Y[0..j-1] */
        for (let i = 0; i <= m; i++) {
            for (let j = 0; j <= n; j++) {
                if (i == 0 || j == 0) {
                    L[i][j] = 0;
                } else if (X[i - 1] == Y[j - 1]) {
                    L[i][j] = L[i - 1][j - 1] + 1;
                } else {
                    L[i][j] = Math.max(L[i - 1][j], L[i][j - 1]);
                }
            }
        }
   
        // Following code is used to print LCS
        let index = L[m][n];
   
        // Create a String length index+1 and
        // fill it with \0
        let lcs = new Array(index + 1);
        lcs.fill('');
   
        // Start from the right-most-bottom-most
        // corner and one by one store characters
        // in lcs[]
        let i = m, j = n;
        while (i > 0 && j > 0) {
            // If current character in X[] and Y
            // are same, then current character
            // is part of LCS
            if (X[i - 1] == Y[j - 1]) {
                // Put current character in result
                lcs[index - 1] = X[i - 1];
                i--;
                j--;
   
                // reduce values of i, j and index
                index--;
            } // If not same, then find the larger of
            // two and go in the direction of larger
            // value
            else if (L[i - 1][j] > L[i][j - 1]) {
                i--;
            } else {
                j--;
            }
        }
        let ans = "";
        for (let x = 0; x < lcs.length; x++) {
            ans += lcs[x];
        }
        return ans;
    }
   
// Returns longest palindromic subsequence
// of str
    function longestPalSubseq(str) {
        // Find reverse of str
        let rev = str;
        rev = reverse(rev);
   
        // Return LCS of str and its reverse
        return lcs(str, rev);
    }
   
    function reverse(str) {
        let ans = "";
        // convert String to character array
        // by using toCharArray
        let try1 = str.split('');
   
        for (let i = try1.length - 1; i >= 0; i--) {
            ans += try1[i];
        }
        return ans;
    }
     
    let str = "GEEKSFORGEEKS";
      document.write(longestPalSubseq(str));
     
    // This code is contributed by suresh07.
</script>


Output: 
 

EEGEE

Time Complexity: O(n*m)
Auxiliary Space: O(n*m)
 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads