[Swift]LeetCode730. 统计不同回文子字符串 | Count Different Palindromic Subsequences

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: https://www.cnblogs.com/strengthen/p/10518830.html 
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

Given a string S, find the number of different non-empty palindromic subsequences in S, and return that number modulo 10^9 + 7.

A subsequence of a string S is obtained by deleting 0 or more characters from S.

A sequence is palindromic if it is equal to the sequence reversed.

Two sequences A_1, A_2, ... and B_1, B_2, ... are different if there is some i for which A_i != B_i.

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 10^9 + 7. 

Note:

  • The length of S will be in the range [1, 1000].
  • Each character S[i] will be in the set {'a', 'b', 'c', 'd'}.

给定一个字符串 S,找出 S 中不同的非空回文子序列个数,并返回该数字与 10^9 + 7 的模。

通过从 S 中删除 0 个或多个字符来获得子字符序列。

如果一个字符序列与它反转后的字符序列一致,那么它是回文字符序列。

如果对于某个  iA_i != B_i,那么 A_1, A_2, ... 和 B_1, B_2, ... 这两个字符序列是不同的。 

示例 1:

输入:
S = 'bccb'
输出:6
解释:
6 个不同的非空回文子字符序列分别为:'b', 'c', 'bb', 'cc', 'bcb', 'bccb'。
注意:'bcb' 虽然出现两次但仅计数一次。

示例 2:

输入:
S = 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba'
输出:104860361
解释:
共有 3104860382 个不同的非空回文子字符序列,对 10^9 + 7 取模为 104860361。 

提示:

  • 字符串 S 的长度将在[1, 1000]范围内。
  • 每个字符 S[i] 将会是集合 {'a', 'b', 'c', 'd'} 中的某一个。

Runtime: 760 ms
Memory Usage: 25.9 MB
 1 class Solution {
 2     func countPalindromicSubsequences(_ S: String) -> Int {
 3         var arr:[Character] = Array(S)
 4         var n:Int = S.count
 5         var M:Int = Int(1e9 + 7)
 6         var dp:[[Int]] = [[Int]](repeating:[Int](repeating:0,count:n),count:n)
 7         for i in 0..<n
 8         {
 9             dp[i][i] = 1
10         }
11         for len in 1..<n
12         {
13             for i in 0..<(n - len)
14             {
15                 var j:Int = i + len
16                 if arr[i] == arr[j]
17                 {
18                     var left:Int = i + 1
19                     var right:Int = j - 1
20                     while (left <= right && arr[left] != arr[i])
21                     {
22                         left += 1
23                     }
24                     while (left <= right && arr[right] != arr[i])
25                     {
26                         right -= 1
27                     }
28                     if left > right
29                     {
30                         dp[i][j] = dp[i + 1][j - 1] * 2 + 2
31                     }
32                     else if left == right
33                     {
34                         dp[i][j] = dp[i + 1][j - 1] * 2 + 1
35                     }
36                     else
37                     {
38                         dp[i][j] = dp[i + 1][j - 1] * 2 - dp[left + 1][right - 1]
39                     }
40                 }
41                 else
42                 {
43                     dp[i][j] = dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1]
44                 }
45                 dp[i][j] = (dp[i][j] < 0) ? dp[i][j] + M : dp[i][j] % M
46             }
47         }
48         return dp[0][n - 1]
49     }
50 }
原文地址:https://www.cnblogs.com/strengthen/p/10518830.html