Sponsored
Sponsored
Use a 2D table to keep track of the longest palindromic subsequence. The idea is to fill out this table by solving smaller subproblems and using their results to build up solutions to bigger ones.
The table, dp[i][j], will store the length of the longest palindromic subsequence in s[i...j]
. Start by assuming that each character is a palindrome of length 1, and fill the table based on whether the characters at the current indices are the same.
Time Complexity: O(n^2), where n is the length of the string, because we need to fill an n x n table.
Space Complexity: O(n^2), for the same reason due to the dp table.
1#include <stdio.h>
2#include <string.h>
3
4int longestPalindromeSubseq(char *s) {
5 int n = strlen(s);
6 int dp[n][n];
7 for (int i = n - 1; i >= 0; i--) {
8 dp[i][i] = 1;
9 for (int j = i + 1; j < n; j++) {
10 if (s[i] == s[j])
11 dp[i][j] = dp[i + 1][j - 1] + 2;
12 else
13 dp[i][j] = (dp[i + 1][j] > dp[i][j - 1]) ? dp[i + 1][j] : dp[i][j - 1];
14 }
15 }
16 return dp[0][n - 1];
17}
18
19int main() {
20 char *s = "bbbab";
21 printf("%d\n", longestPalindromeSubseq(s));
22 return 0;
23}
We initialize a 2D table with zero values and then iterate over the string in reverse to ensure that we only use already computed values for dp[i+1][j] and dp[i][j-1] when needed.
This approach defines a recursive function that explores all potential palindromic subsequences, using memoization to store results of overlapping subproblems, thereby avoiding redundant calculations. The function checks if the characters at current indices are equal and proceeds based on that, with memoization avoiding recalculations.
Time Complexity: O(n^2), where n is the length of the string due to memoization.
Space Complexity: O(n^2) for the memoization table.
1#include <iostream>
#include <vector>
using namespace std;
class Solution {
vector<vector<int>> memo;
public:
int longestPalindromeSubseq(string s) {
int n = s.size();
memo.resize(n, vector<int>(n, -1));
return helper(s, 0, n - 1);
}
int helper(string &s, int l, int r) {
if (l > r) return 0;
if (l == r) return 1;
if (memo[l][r] != -1) return memo[l][r];
if (s[l] == s[r]) {
memo[l][r] = 2 + helper(s, l + 1, r - 1);
} else {
memo[l][r] = max(helper(s, l + 1, r), helper(s, l, r - 1));
}
return memo[l][r];
}
};
int main() {
Solution solution;
cout << solution.longestPalindromeSubseq("bbbab") << endl;
return 0;
}
C++ implementation using a vector for memoization, aligning with typical approaches of recursive solutions in C++ by utilizing stack memory efficiently for recursive calls.