好多牛牛

好多牛牛

题目描述

给出一个字符串S,牛牛想知道这个字符串有多少个子序列等于"niuniu"
子序列可以通过在原串上删除任意个字符(包括0个字符和全部字符)得到。
为了防止答案过大,答案对1e9+7取模

示例输入
“niuniniu”

输出
3

说明
删除第4,5个字符可以得到"niuniu"
删除第5,6个字符可以得到"niuniu"
删除第6,7个字符可以得到"niuniu"

解析

本题目使用动态规划的算法求解。
案例中,在niuniniu中找模式串niuniu,我们在输入串中匹配模式串,模式串中每个字符的匹配次数只和前一个字符有关,因为只有出现了前一个字符,后一个字符才能匹配成功,除了第一个字符(出现一次匹配一次,因为没有前缀)。

输入\模式串匹配次数niuniu
null000000
n100000
i110000
u111000
n211100
i231110
n331210
i361230
u367233

从上表可以看出,每输入一个字符,对应模式串的子串匹配量就增加前一个字符的匹配量,用一个简单的例子表示:

aaabb中匹配模式串ab,当输入到 b 的时候,a 已经输入了 3 次,因此模式串 ab 的匹配次数要加上模式串前一个字符 a 的匹配次数;当输入第二个 b 的时候,再加上模式串中前一个字符的匹配次数,因此ab一共匹配了6次。

案例中,当输入最后一个u的时候,子串ni已经匹配了6次,即是说,在新输入的u前面,有6个ni可以和新的u组成niu,因此,模式串niu的匹配次数 1(原有)+6=7;子串niuni匹配了3次,模式串niuniu的匹配次数 0+3=3

设一个长度为模式串pattern.size()+1的数组dp[],为了统一计算,即每个字符只和前一个字符匹配次数有关,设 dp[0] = 1,这样每次出现模式串的第一个字符,也可以计算dp[1]+=dp[0],即自增。

const int mod = 1e9+7;
class Solution {
public:
    int solve(string s) {
        // write code here
        string pattern = "niuniu";
        vector<int> dp(pattern.size()+1, 0);
        dp[0] = 1;
        
        for(char &c : s)
            for(int i = 0; i < pat.size(); i++)
                if(pattern[i] == c)
                    dp[i+1] = (dp[i+1] + dp[i]) % mod;

        return dp[pattern.size()];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值