4.21 leetcode -21 regular-expression-matching

题目描述

Implement regular expression matching with support for'.'and'*'.
'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true

isMatch("aab", "c*a*b") → true


这题情况有点多,*是要搭配的,其余都是单体作战。比较麻烦的应该是这么一种情况
"abababababab",".*b","a.*";

最难的“ababxxxabab”,".*x.*";情况简直多。


这题需要动态规划来做,是我最不会的动态规划,专门搞了一个章节学习:

以下代码是看了牛客大神后改了一些的代码。

解释一下,新建了一个dp[n1+1][n2+1]的控件,其中dp[i+1][j+1]表示,s的0-i和p的0-j是否匹配

1:第一个for循环,是初始化,存在一种情况,s没有,但是p有很多x*,那么也是匹配的,所以全部得true一下。

     小瑕疵(dp[0][1]其实没有初始化)

2:就进入dp循环,分几种情况考虑

     1)首先假如碰到了'.'那么,他直接和斜对角那个值相等,也就是i和j各-1的值,假如是相等的,同理

     2 )其次,碰到了‘*’分来情况考虑,要是,j-1的数和i-1的数不等,说明这个*得孤独终老(算作无效),他的值也就和他的j-2一样,因为有他没他没差别;另一种情况,相等的,那就复杂了,首先,看j-2,没有他是不是true,没有他都是true,那么你存在着也肯定是true呀;再看,假如我起作用了,那么i-1,看看是否是true,假如那会儿我就能处理你,多你一个不多,继续是true(这里隐含了一个情况,就是i-1,j-2假如这个是true了,那么i-1,j肯定也是true,所以不用列进去,而牛客大神的dp[i+1][j],也就是j-1这因素,j-1假如ok,那么i-1,j-2也肯定ok,那么i-1,也肯定ok,那么就回到了我之前推导,所以我觉得不加可以)

class Solution {
public:
    bool isMatch(const char *s, const char *p) {
        if(s == NULL || p == NULL)
            return false;
        int n1 = 0;
        while(s[n1] != '\0')
            n1++;
        int n2 = 0;
        while(p[n2] != '\0')
            n2++;

        bool** dp  = (bool **)malloc(sizeof(bool*)*(n1+1));//为二维数组分配,马丹,这里调了很久,不能一次性
        for (int i = 0; i < (n1+1); ++i){
            dp[i] = (bool*)malloc(sizeof(bool)*(n2+1));
        }
        dp[0][0]=true;
        for (int i = 1; i < n2; i++) 
        {
            if (p[i] == '*' && dp[0][i-1]) 
            {
                dp[0][i+1] = true;
            }
            else
                dp[0][i+1] = false;
    	} 
	for(int i = 0;i < n1;i++)
            {
            for(int j = 0;j < n2;j++)
                {
                if (p[j] == '.') {
                    dp[i+1][j+1] = dp[i][j];
                }
                if (p[j] == s[i]) {
                    dp[i+1][j+1] = dp[i][j];
                } 

                if (p[j] == '*' && j > 0) {
                    if (p[j-1] != s[i] && p[j-1] != '.') {
                        dp[i+1][j+1] = dp[i+1][j-1];
                    } else {
                        dp[i+1][j+1] = (dp[i][j+1] || dp[i+1][j-1]);//主要就是这部分的理解,牛客大神还有dp[i+1][j]
                                                           //这部分,我觉得没有意义删掉了,从测试案例来说,没问题
                    }
                }
         }
        }

        return dp[n1][n2];
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值