Given a string s, return the number of different non-empty palindromic subsequences in s
. Since the answer may be very large, return it modulo 109 + 7
.
A subsequence of a string is obtained by deleting zero or more characters from the string.
A sequence is palindromic if it is equal to the sequence reversed.
Two sequences a1, a2, ...
and b1, b2, ...
are different if there is some i
for which ai != bi
.
Example 1:
Input: s = "bccb" Output: 6 Explanation: The 6 different non-empty palindromic subsequences are 'b', 'c', 'bb', 'cc', 'bcb', 'bccb'. Note that 'bcb' is counted only once, even though it occurs twice.
Example 2:
Input: s = "abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba" Output: 104860361 Explanation: There are 3104860382 different non-empty palindromic subsequences, which is 104860361 modulo 109 + 7.
Constraints:
1 <= s.length <= 1000
s[i]
is either 'a'
, 'b'
, 'c'
, or 'd'
.This problem asks to find the number of different non-empty palindromic subsequences in a given string. 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. A palindromic sequence reads the same forwards and backward.
The most efficient approach is using dynamic programming. We'll build a 3D DP table where:
dp[i][j][k]
represents the number of distinct palindromic subsequences of length at least 1 within the substring s[i...j]
that end with character k
('a'=0, 'b'=1, 'c'=2, 'd'=3).The base cases are when i == j
: dp[i][i][k]
is 1 if s[i]
is character k
, otherwise 0.
The recursive relation is built as follows:
s[i] == s[j] == c
: If the characters at both ends of the substring are the same and equal to character c
, then we have several possibilities:
s[i+1...j-1]
.c
(s[i]
, s[j]
). This adds 2 to the count (unless the substring s[i+1...j-1]
already contains c
, in which case it would be already included).s[i] == c
or s[j] == c
: If only one of the ends matches character c
, then the count is simply inherited from the smaller substring that ends in c
.
s[i] != c
and s[j] != c
: If neither end matches character c
, then the count is inherited from the inner substring s[i+1...j-1]
.
The final answer is the sum of dp[0][n-1][k]
for all k
(0 to 3), representing the total number of distinct palindromic subsequences in the entire string.
Time Complexity: O(n^2 * 4), where n is the length of the string. We iterate through all possible substrings (O(n^2)) and for each substring, consider each of the 4 possible characters ('a', 'b', 'c', 'd').
Space Complexity: O(n^2 * 4) to store the DP table.
The code provided in the original response is well-structured and efficient. It directly implements the dynamic programming solution described above. Note that the modulo operator (%) is used to prevent integer overflow, as the number of palindromic subsequences can become very large. Each language version shows a slightly different approach for handling this optimization, but the core logic is identical.