[
string
dp
palindrome
]
Leetcode 0730 Count Different Palindromic Subsequences
Problem statement
https://leetcode.com/problems/count-different-palindromic-subsequences/
Solution
The idea is to define dp[i, j] be the answer for substing S[i:j+1] (we also count empty substing, so we will subtract 1 in the end). Then let us find the leftest and the rightest a in this substing: it will be number of unique substrings with ending elements equal to a. In the same way we evaluate number of substrings with ending elements b, c, d. Also we need to check one more border case: substrings with length 1.
Complexity
Time complexity is O(n^2d), where d = 4 here is size of alphabet, space complexity is O(n^2).
Code
class Solution:
def countPalindromicSubsequences(self, S):
def letter_get(s, letter, dir):
res, cur = [-1]*len(s), -1
for i in range(len(s))[::dir]:
if s[i] == letter: cur = i
res[i] = cur
return res
corrs_dir = defaultdict(list)
corrs_inv = defaultdict(list)
for letter in "abcd":
corrs_dir[letter] = letter_get(S, letter, 1)
corrs_inv[letter] = letter_get(S, letter, -1)
n, MOD = len(S), 10**9 + 7
@lru_cache(None)
def dp(i, j):
if i > j: return 1
ans = 1
for letter in "abcd":
i0 = corrs_inv[letter][i]
j0 = corrs_dir[letter][j]
if i <= i0 <= j: ans += 1 #single letter
if -1 < i0 < j0: ans += dp(i0+1, j0-1) #...X_X... case
return ans % MOD
return dp(0, n-1) - 1