【算法题】2484. 统计回文子序列数目

题目:

给你数字字符串 s ,请你返回 s 中长度为 5 的 回文子序列 数目。由于答案可能很大,请你将答案对 109 + 7 取余 后返回。

提示:

如果一个字符串从前往后和从后往前读相同,那么它是 回文字符串 。
子序列是一个字符串中删除若干个字符后,不改变字符顺序,剩余字符构成的字符串。

示例 1:

输入:s = “103301”
输出:2
解释:
总共有 6 长度为 5 的子序列:“10330” ,“10331” ,“10301” ,“10301” ,“13301” ,“03301” 。
它们中有两个(都是 “10301”)是回文的。
示例 2:

输入:s = “0000000”
输出:21
解释:所有 21 个长度为 5 的子序列都是 “00000” ,都是回文的。
示例 3:

输入:s = “9999900000”
输出:2
解释:仅有的两个回文子序列是 “99999” 和 “00000” 。

提示:

1 <= s.length <= 10^4
s 只包含数字字符。

#Java代码

````
 class Solution {
private static final long MOD = (long) 1e9 + 7;

public int countPalindromes(String S) {
    var s = S.toCharArray();
    int[] pre = new int[10], suf = new int[10];
    int[][] pre2 = new int[10][10], suf2 = new int[10][10];
    for (var i = s.length - 1; i >= 0; --i) {
        var d = s[i] - '0';
        for (var j = 0; j < 10; ++j)
            suf2[d][j] += suf[j];
        ++suf[d];
    }

    var ans = 0L;
    for (var d : s) {
        d -= '0';
        --suf[d];
        for (var j = 0; j < 10; ++j)
            suf2[d][j] -= suf[j]; // 撤销
        for (var j = 0; j < 10; ++j)
            for (var k = 0; k < 10; ++k)
                ans += (long) pre2[j][k] * suf2[j][k]; // 枚举所有字符组合
        for (var j = 0; j < 10; ++j)
            pre2[d][j] += pre[j];
        ++pre[d];
    }
    return (int) (ans % MOD);
}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值