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.

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

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.