返回介绍

solution / 0700-0799 / 0730.Count Different Palindromic Subsequences / README

发布于 2024-06-17 01:03:35 字数 5405 浏览 0 评论 0 收藏 0

730. 统计不同回文子序列

English Version

题目描述

给你一个字符串 s ,返回 s 中不同的非空回文子序列个数 。由于答案可能很大,请返回对 109 + 7 取余 的结果。

字符串的子序列可以经由字符串删除 0 个或多个字符获得。

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

如果存在某个 i , 满足 ai != bi ,则两个序列 a1, a2, ... 和 b1, b2, ... 不同。

 

示例 1:

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

示例 2:

输入:s = 'abcdabcdabcdabcdabcdabcdabcdabcddcbadcbadcbadcbadcbadcbadcbadcba'
输出:104860361
解释:共有 3104860382 个不同的非空回文子序列,104860361 是对 109 + 7 取余后的值。

 

提示:

  • 1 <= s.length <= 1000
  • s[i] 仅包含 'a''b''c' 或 'd' 

解法

方法一:区间 DP

class Solution:
  def countPalindromicSubsequences(self, s: str) -> int:
    mod = 10**9 + 7
    n = len(s)
    dp = [[[0] * 4 for _ in range(n)] for _ in range(n)]
    for i, c in enumerate(s):
      dp[i][i][ord(c) - ord('a')] = 1
    for l in range(2, n + 1):
      for i in range(n - l + 1):
        j = i + l - 1
        for c in 'abcd':
          k = ord(c) - ord('a')
          if s[i] == s[j] == c:
            dp[i][j][k] = 2 + sum(dp[i + 1][j - 1])
          elif s[i] == c:
            dp[i][j][k] = dp[i][j - 1][k]
          elif s[j] == c:
            dp[i][j][k] = dp[i + 1][j][k]
          else:
            dp[i][j][k] = dp[i + 1][j - 1][k]
    return sum(dp[0][-1]) % mod
class Solution {
  private final int MOD = (int) 1e9 + 7;

  public int countPalindromicSubsequences(String s) {
    int n = s.length();
    long[][][] dp = new long[n][n][4];
    for (int i = 0; i < n; ++i) {
      dp[i][i][s.charAt(i) - 'a'] = 1;
    }
    for (int l = 2; l <= n; ++l) {
      for (int i = 0; i + l <= n; ++i) {
        int j = i + l - 1;
        for (char c = 'a'; c <= 'd'; ++c) {
          int k = c - 'a';
          if (s.charAt(i) == c && s.charAt(j) == c) {
            dp[i][j][k] = 2 + dp[i + 1][j - 1][0] + dp[i + 1][j - 1][1]
              + dp[i + 1][j - 1][2] + dp[i + 1][j - 1][3];
            dp[i][j][k] %= MOD;
          } else if (s.charAt(i) == c) {
            dp[i][j][k] = dp[i][j - 1][k];
          } else if (s.charAt(j) == c) {
            dp[i][j][k] = dp[i + 1][j][k];
          } else {
            dp[i][j][k] = dp[i + 1][j - 1][k];
          }
        }
      }
    }
    long ans = 0;
    for (int k = 0; k < 4; ++k) {
      ans += dp[0][n - 1][k];
    }
    return (int) (ans % MOD);
  }
}
using ll = long long;

class Solution {
public:
  int countPalindromicSubsequences(string s) {
    int mod = 1e9 + 7;
    int n = s.size();
    vector<vector<vector<ll>>> dp(n, vector<vector<ll>>(n, vector<ll>(4)));
    for (int i = 0; i < n; ++i) dp[i][i][s[i] - 'a'] = 1;
    for (int l = 2; l <= n; ++l) {
      for (int i = 0; i + l <= n; ++i) {
        int j = i + l - 1;
        for (char c = 'a'; c <= 'd'; ++c) {
          int k = c - 'a';
          if (s[i] == c && s[j] == c)
            dp[i][j][k] = 2 + accumulate(dp[i + 1][j - 1].begin(), dp[i + 1][j - 1].end(), 0ll) % mod;
          else if (s[i] == c)
            dp[i][j][k] = dp[i][j - 1][k];
          else if (s[j] == c)
            dp[i][j][k] = dp[i + 1][j][k];
          else
            dp[i][j][k] = dp[i + 1][j - 1][k];
        }
      }
    }
    ll ans = accumulate(dp[0][n - 1].begin(), dp[0][n - 1].end(), 0ll);
    return (int) (ans % mod);
  }
};
func countPalindromicSubsequences(s string) int {
  mod := int(1e9) + 7
  n := len(s)
  dp := make([][][]int, n)
  for i := range dp {
    dp[i] = make([][]int, n)
    for j := range dp[i] {
      dp[i][j] = make([]int, 4)
    }
  }
  for i, c := range s {
    dp[i][i][c-'a'] = 1
  }
  for l := 2; l <= n; l++ {
    for i := 0; i+l <= n; i++ {
      j := i + l - 1
      for _, c := range [4]byte{'a', 'b', 'c', 'd'} {
        k := int(c - 'a')
        if s[i] == c && s[j] == c {
          dp[i][j][k] = 2 + (dp[i+1][j-1][0]+dp[i+1][j-1][1]+dp[i+1][j-1][2]+dp[i+1][j-1][3])%mod
        } else if s[i] == c {
          dp[i][j][k] = dp[i][j-1][k]
        } else if s[j] == c {
          dp[i][j][k] = dp[i+1][j][k]
        } else {
          dp[i][j][k] = dp[i+1][j-1][k]
        }
      }
    }
  }
  ans := 0
  for _, v := range dp[0][n-1] {
    ans += v
  }
  return ans % mod
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文