LeetCode 第十题 正则表达式匹配 笔记

文章讲述了如何使用动态规划解决一个字符串匹配问题,涉及*的重复次数判断。作者介绍了常规思路中的动态规划方法,以及两位大佬提出的简化版神仙思路,分别通过不同的函数设计和分类简化了算法过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

菜鸟寒假刷C,于力扣十题处,苦思,思之三日,终得解,现记之。

题目:

一、常规思路:

        本题难点就难在“ * ”重复的次数是未知的,关键就是如何去处理这个“ * ”。在这里,我们选用动态规划的方法便于理解。

        “ * ”的情况大致可分为三种:重复0次,重复1次,以及重复2次及以上。重复0次则n[i][j]=n[i][j-2](n是二维数组,其中i对应着字符串s,j对应字符串p), 重复一次则n[i][j]=n[i-1][j-2];当重复两次及以上时,则令n[i][j]=n[i-1][j];相当于舍弃s的一个字符后,再将剩下的与p进行判断。

        解决了最难的点后,接下来我们讨论如何去定义n,和以往的定义n[lens][lenp]不同,这次我们选择定义n[lens+1][lenp+1]。这样定义有一个好处,就是不用将首项与中间项进行分开讨论,这里的“ +1 ”实际上相当于在两个字符串之前都先增添了一个相同的项,那接下来只用去讨论包括原来的首项在内的分项即可,无需再进行分类讨论,简化了算法。

        最终,总的代码如下:

二、神仙思路:(有幸观看到了两位大佬对此题的解答,惊为天人,故记之)

        (一)思路一:在前文中我们已经提到了如何去处理“ * ”的重复次数问题,而我们处理的方法是用两个循环去遍历两个字符串。而第一位大佬,则另辟蹊径,直接将函数当做循环来使用(如当“ * ”重复0次时:isMatch(s,p)=isMatch(s,p+2),即将p+2当做一个新的字符串来使用),但因为没有用二维数组去定义,这里,他选择创建一个新的函数 first_match 来判断首字母是否相同:

                        

        不过同时,也因为他定义了这样一个函数,在讨论“ * ”重复一次或是两次及以上时,这两中情况可以进行合并:

            

最终,整体代码为:

        (二)思路二:在上一位大佬思路的基础上,这位大佬选择了将算法更进一步的简化:

        他一共只将所有的情况分为了三类:s,p均为空;当s,p均不为空时,p[0]=s[0]或p[0]='.';当p[0]!=s[0]且p[0]!='.',而p[1]='*' 这三种情况。下面我们来依次分析这三种:

        1、s,p均为空:这类最简单,直接判断二者是否同时为空即可:

                                   

        2、s,p均不为空时,p[0]=s[0]或p[0]='.' :此时的p[1]有两种可能,若p[1]='*',那么isMatch(s,p)=isMatch(s+1,p);若p[1]!='*',那么 isMatch(s,p)=isMatch(s+1,p+1):

        3、p[0]!=s[0]且p[0]!='.',而p[1]='*':此时 isMatch(s,p)=isMatch(s,p+2):

                      

        最终,将三种情况进行并列,得到了最终代码:

return s[0]=='\0'&&p[0]=='\0'||s[0]!='\0'&&p[0]!='\0'&&(p[0]=='.'||p[0]==s[0])&&(p[1]=='*'?isMatch(s +1,p):isMatch(s+1,p+1))||p[0]!='\0'&&p[1]=='*'&&isMatch(s,p+2);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值