【LeetCode每日一题:1759. 统计同构子字符串的数目~~~数学公式+双指针+动态规划】

题目描述

给你一个字符串 s ,返回 s 中 同构子字符串 的数目。由于答案可能很大,只需返回对 109 + 7 取余 后的结果。

同构字符串 的定义为:如果一个字符串中的所有字符都相同,那么该字符串就是同构字符串。

子字符串 是字符串中的一个连续字符序列。

示例 1:

输入:s = “abbcccaa”
输出:13
解释:同构子字符串如下所列:
“a” 出现 3 次。
“aa” 出现 1 次。
“b” 出现 2 次。
“bb” 出现 1 次。
“c” 出现 3 次。
“cc” 出现 2 次。
“ccc” 出现 1 次。
3 + 1 + 2 + 1 + 3 + 2 + 1 = 13
示例 2:

输入:s = “xy”
输出:2
解释:同构子字符串是 “x” 和 “y” 。
示例 3:

输入:s = “zzzzz”
输出:15

提示:

1 <= s.length <= 105
s 由小写字符串组成

求解思路

求解思路1:数学公式+双指针:根据题目的意思,我们对字符串进行分组,然后通过循环遍历求解每一个组对最后结果的贡献即可。每一个组对结果的贡献公式:i*(i+1)/2
求解思路2:动态规划:每一个字符都对最后的结果贡献为1,初始化就可以得出,然后在循环遍历的过程中,我们可以判断当前位置的字符和之前位置的字符是否相等,如果相等,那么当前位置的值等于前一个位置的值+1,如果不相等,那么就是1。循环遍历,对最终的结果取模。

实现代码

实现方式1:数学公式+双指针
class Solution {
    
    public static final int mod=(int)(1e9+7);

    public int countHomogenous(String s) {
        char pre=s.charAt(0);
        int cnt=0;
        long res=0;
        for(int i=0;i<s.length();i++){
            if(s.charAt(i)==pre){
                cnt++;
            }else{
                res+=(long)(cnt+1)*cnt/2;
                cnt=1;
                pre=s.charAt(i);
            }
        }
        res+=(long)(cnt+1)*cnt/2;
        return (int)(res%mod);
    }
}
实现方式2:动态规划
class Solution {
    public int countHomogenous(String s) {
        int mod=1000000007;
        char[] arr = s.toCharArray();
        int n = s.length();
        int[] dp = new int[n];
        dp[0] = 1;
        long res = 1;
        for (int i = 1; i < n; i++) {
            dp[i] = arr[i] == arr[i - 1] ? dp[i - 1] + 1 : 1;
            res=(res+dp[i])%mod;
        }
        return (int)(res%mod);
    }
}

运行结果

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

硕风和炜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值