Print Longest Palindromic Subsequence

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)

In this post a solution to print the longest palindromic subsequence is discussed.

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

filter_none

edit
close

play_arrow

link
brightness_4
code

/* 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;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to print longest palindromic 
//subsequence 
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));
  
    }
}

chevron_right



Output:

EEGEE


My Personal Notes arrow_drop_up

This article is contributed by Kartik. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : Rajput-Ji