Longest Palindromic Subsequence - Bottom-up + Top-down DP explained
Problem Statement:
Given a string s
, find the longest palindromic subsequence's length in s
.
A subsequence is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements.
Example 1:
Input: s = "bbbab" Output: 4 Explanation: One possible longest palindromic subsequence is "bbbb".
Example 2:
Input: s = "cbbd" Output: 2 Explanation: One possible longest palindromic subsequence is "bb".
Constraints:
1 <= s.length <= 1000
s
consists only of lowercase English letters.
Solution:
Bottom-up Approach
We denote dp[i][j]
as the answer for the string s[i...j]
. Hence final answer is dp[0][n-1]
where n
is length of string s
.
Now, to get dp[i][j]
, we firstly start with the base case that is if i==j
or i==j+1
. Both of these are trivial to calculate. For other cases, we have three possiilities. Multiple of these can be true at a a time but the answer will still hold true.
- The subsequence lies in
s[i+1..j]
- The subsequence lies in
s[i..j-1]
s[i]
ands[j]
are part of the subsequence
We take a maximum of all these cases as the answer.
int longestPalindromeSubseq(string s)
{
int n = s.length();
vector<vector<int>> dp (n, vector<int>(n, -1));
for (int len=1; len<=n; len++)
{
for (int i=0; i+len-1<n; i++)
{
int j = i+len-1;
if (len==1) dp[i][j] = 1;
else if (len==2) dp[i][j] = ((s[i]==s[j]) ? 2 : 1);
else
{
int a = dp[i+1][j-1] + ((s[i]==s[j])?2:0);
int b = dp[i+1][j];
int c = dp[i][j-1];
dp[i][j] = max(max(a,b),c);
}
}
}
return dp[0][n-1];
}
Top-down approach
int helper(string &s, vector<vector<int>>&dp, int i, int j)
{
if (dp[i][j]!=-1) return dp[i][j];
if (i>j) return 0;
if (i==j) return 1;
if (s[i]==s[j]) return dp[i][j] = 2+helper(s,dp,i+1,j-1);
return dp[i][j] = max(helper(s,dp,i+1,j), helper(s,dp,i,j-1));
}
int longestPalindromeSubseq(string s)
{
int n = s.length();
vector<vector<int>> dp(n, vector<int>(n,-1));
return helper(s, dp, 0, s.length()-1);
}
Analysis:
TC: $O(n^2)$ SC: $O(n^2)$