Count total palindromic subsequences using dynamic programming.
Problem Statement
Examples
Input: s = "abcd"
Output: 4
Explanation: Combining the input according to Count Palindromic Subsequences logic yields 4.
Input: s = "aab"
Output: 4
Explanation: Combining the input according to Count Palindromic Subsequences logic yields 4.
Input: s = "aaaa"
Output: 15
Explanation: Combining the input according to Count Palindromic Subsequences logic yields 15.
Complexity
Time Complexity: O(N²)
Space Complexity: O(N²)
Hints
Editorial & Approach
Problem Overview & Intuition
Let dp[i][j] be the number of palindromic subsequences in s[i...j]. By the inclusion-exclusion principle: when s[i] !== s[j], count is dp[i+1][j] + dp[i][j-1] - dp[i+1][j-1]. When s[i] === s[j], any palindrome in s[i+1...j-1] can be wrapped by s[i] and s[j], plus the pair {s[i], s[j]} itself.
Step-by-Step Approach
- Initialize
dp[n][n]table with BigInt values modulo10^9 + 7. - Base cases:
dp[i][i] = 1. - Iterate interval length
lenfrom2ton. - If
s[i] === s[j]:dp[i][j] = (dp[i + 1][j] + dp[i][j - 1] + 1) % MOD. - Else:
dp[i][j] = (dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] + MOD) % MOD. - Return
Number(dp[0][n - 1]).
Optimal Implementation (JavaScript)
function countPalindromicSubsequences(s) {
const n = s.length;
const MOD = 1000000007n;
const dp = Array.from({ length: n }, () => new Array(n).fill(0n));
for (let i = 0; i < n; i++) dp[i][i] = 1n;
for (let len = 2; len <= n; len++) {
for (let i = 0; i <= n - len; i++) {
const j = i + len - 1;
if (s[i] === s[j]) {
dp[i][j] = (dp[i + 1][j] + dp[i][j - 1] + 1n) % MOD;
} else {
dp[i][j] = (dp[i + 1][j] + dp[i][j - 1] - dp[i + 1][j - 1] + MOD) % MOD;
}
}
}
return Number(dp[0][n - 1]);
}
Complexity Analysis
Edge Cases & Corner Traps Handled
- All identical characters "aaaa": returns 2^N - 1.
- All distinct characters: returns N.