动态规划之两个数组的 dp(下)

正则表达式匹配

题目:正则表达式匹配

在这里插入图片描述
思路

  • 状态表示:选第一个字符串的 [0, i]区间和第二个字符串的 [0, j]区间作为研究对象
    dp[i][j]表示字符串 s1 [1, i]区间和字符串 s2[1, j]区间是否可以匹配

  • 状态转移方程:根据s1s2的最后一个位置,进行讨论

    • p[j]a - z时,p[j] == s[i] && dp[i - 1][j - 1] == true --- > true
    • p[j] == '.'时,dp[i - 1][j - 1] == true --- > true
    • p[j] == '*'时,再细分
      • p[j - 1] == '.',对其“翻译”
        • 空串,dp[i][j - 2]
        • 一个点,dp[i - 1][j - 2]
        • 两个点,dp[i - 2][j - 2]
        • ... ... ...;上述有一个true,就是true

        优化:p[j - 1] == '.'

        1. 我们注意到
        • dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2] || dp[i -2][j -2] || ... ...
        • dp[i - 1][j] = dp[i - 1][j -2] || dp[i - 2][j - 2] || dp[i -3][j -2] || ... ...
        • 所以,dp[i][j] = dp[i][j - 2] || dp[i - 1][j]
      • p[j - 1]a - z时,对其“翻译”
        • 空串,dp[i][j - 2]
        • 匹配一个,然后保留,p[j - 1] == s[i] && dp[i - 1][j]

综上,状态转移方程为:dp[i][j]

  • p[j]能匹配时,即s[i] == p[j] || p[j] = '.',此时看看&& dp[i - 1][j -1]
  • dp[i][j -2] || (p[j -1] == ',' || p[j -1] == s[i]) && dp[i -1][j]
  • 初始化:引入空串,注意下标映射

    • 初始化整个数组为false
    • dp[0][0]表示两个,初始化为 true
    • 第一列表示 p 为空串,不可能匹配上s 串;
    • 第一行表示s为空串,偶数位置连续为*才为true否则跳出;
  • 填表顺序:从上往下,从左往右

  • 返回值:dp[m][n]

C++代码

class Solution 
{
   
   
public:
    bool isMatch(string s, string p) 
    {
   
   
        int m = s.size(), n = p.size();
        s = " " + s, p = " " + p;
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1));
        dp[0][0] = true;
        for (int i = 2; i <= n; i += 2)
            if (p[i] == '*')
                dp[0][i] = true;
            else
                break;

        for (int i = 1; i <= m; ++i)
            for (int j = 1;
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值