DEV Community

Dolly Sharma
Dolly Sharma

Posted on

πŸ“˜ Longest Palindromic Subsequence (LPS)

πŸ”Ή Key Idea (VERY IMPORTANT πŸ”₯)

πŸ‘‰ Convert LPS β†’ LCS

LPS(s) = LCS(s, reverse(s))
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Why does this work?

  • Palindrome = same forward & backward
  • So if we reverse string and find LCS β†’ we get longest palindrome subsequence

πŸ”Ή Your Code Explained

string t = s;
reverse(t.begin(), t.end());
return lcs(s, t);
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ Steps:

  1. Copy string β†’ t
  2. Reverse it
  3. Find LCS between s and t

πŸ”Ή Example

s = "bbabcbcab"
Enter fullscreen mode Exit fullscreen mode

Reverse:

t = "bacbcbabb"
Enter fullscreen mode Exit fullscreen mode

πŸ‘‰ LCS = "babcbab" (length = 7)


πŸ”₯ Full Code (Clean)

int lcs(string s1, string s2) {
    int n = s1.size(), m = s2.size();
    vector<vector<int>> dp(n+1, vector<int>(m+1, 0));

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(s1[i-1] == s2[j-1])
                dp[i][j] = 1 + dp[i-1][j-1];
            else
                dp[i][j] = max(dp[i-1][j], dp[i][j-1]);
        }
    }
    return dp[n][m];
}

int longestPalindromeSubsequence(string s) {
    string t = s;
    reverse(t.begin(), t.end());
    return lcs(s, t);
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Space Optimized Version πŸš€

int lcs(string s1, string s2) {
    int n = s1.size(), m = s2.size();
    vector<int> prev(m+1, 0), curr(m+1, 0);

    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            if(s1[i-1] == s2[j-1])
                curr[j] = 1 + prev[j-1];
            else
                curr[j] = max(prev[j], curr[j-1]);
        }
        prev = curr;
    }
    return prev[m];
}
Enter fullscreen mode Exit fullscreen mode

πŸ”₯ Print Longest Palindromic Subsequence

πŸ‘‰ Just print LCS of s and reverse(s)

string printLPS(string s) {
    string t = s;
    reverse(t.begin(), t.end());

    int n = s.size();
    vector<vector<int>> dp(n+1, vector<int>(n+1, 0));

    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(s[i-1]==t[j-1])
                dp[i][j]=1+dp[i-1][j-1];
            else
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
        }
    }

    // backtrack
    string ans="";
    int i=n,j=n;
    while(i>0 && j>0){
        if(s[i-1]==t[j-1]){
            ans+=s[i-1];
            i--; j--;
        }
        else if(dp[i-1][j]>dp[i][j-1]) i--;
        else j--;
    }

    reverse(ans.begin(), ans.end());
    return ans;
}
Enter fullscreen mode Exit fullscreen mode

πŸ”Ή Complexity

Metric Value
Time O(nΒ²)
Space O(nΒ²) β†’ optimized to O(n)

🧠 Important Observations

  • LPS is a subsequence, not substring
  • Works even if characters are not continuous
  • Always think:

β€œReverse + LCS”


πŸ”₯ Related Problems

  • Minimum insertions to make palindrome:
n - LPS
Enter fullscreen mode Exit fullscreen mode
  • Minimum deletions:
n - LPS
Enter fullscreen mode Exit fullscreen mode

⚑ Interview Tip

If asked:

β€œLongest palindromic subsequence?”

πŸ‘‰ Say instantly:

β€œWe can solve it using LCS between string and its reverse.”


If you want next πŸš€
I can show:
βœ… Direct DP without LCS trick
βœ… Palindromic substring (different problem ⚠️)
βœ… Hard variations

Just tell me πŸ‘

Top comments (0)