LeetCode in Python 10. Regular Expression Matching (正则表达式匹配)

ops/2024/11/8 22:51:10/

正则表达式匹配涉及到两个字符串的匹配问题,类似于寻找最大公共子串,可使用动态规划思想解决。重点和难点在于如何构建正确的状态转移方程。

示例:

图1 正则表达式匹配输入输出 

代码:

python">class Solution:def isMatch(self, s: str, p: str) -> bool:m, n = len(s), len(p)dp = [[False] * (n + 1) for _ in range(m + 1)]dp[0][0] = Truefor j in range(1, n + 1):if p[j - 1] == '*':dp[0][j] = dp[0][j - 2]for i in range(1, m + 1):for j in range(1, n + 1):if p[j - 1] == s[i - 1] or p[j - 1] == '.':dp[i][j] = dp[i - 1][j - 1]elif p[j - 1] == '*':if p[j - 2] != s[i - 1] and p[j - 2] != '.':dp[i][j] = dp[i][j - 2]else:dp[i][j] = dp[i - 1][j] or dp[i][j - 2]return dp[m][n]  

解释:

1)dp是一个储存是否可以匹配的状态矩阵,大小为(m + 1)*(n + 1),其中首行首列分别表示字符串s为空和字符串p为空的情况。其中dp[0][0]代表s,p两者均为空,显然能匹配。对于s为空而p不为空的情况(即对应dp的首行dp[0][j])是否能匹配取决于p中的字符,若为‘*’则可消除前一个字符使其为空,匹配成功。反之若不为‘*’,则无法匹配成功。故此需要初始化首行:

(ps:状态转移矩阵dp大小为(m + 1)*(n + 1),首行首列代表字符串为空的情况,故dp[i][j]对应s[i-1]和p[j-1])。

        m, n = len(s), len(p)

        dp = [[False] * (n + 1) for _ in range(m + 1)]

        dp[0][0] = True

        for j in range(1, n + 1):

                if p[j - 1] == '*':

                        dp[0][j] = dp[0][j - 2]

2)状态转移主要是判断p中的字符:

        若其为a-z的小写字母或字符‘.’,则直接与s中对应位置比较即可,若相同则dp[i][j] == dp[i - 1][j - 1],这里需要注意字符‘.’可匹配任意字符,可归为p[i][j]==s[i][i]这类情况。

        if p[j - 1] == s[i - 1] or p[j - 1] == '.':

                dp[i][j] = dp[i - 1][j - 1]

        若为字符‘*’,则需要考虑两种情况:

        1.字符'*'消除前一个字符,即p[j - 1] * 整体为空。出现此类情况是因为我们不想选择p[j - 1],即p[j - 1]与对应位置的s[i - 1]不相等(需要注意的是这里的p[j - 1]不等于s[i - 1]包含两种情况,一是两者均为小写字母且不等,二是p[j - 1]不为‘.’)

         2.字符‘*’复制一次前一个字符,即p[j - 1] *=p[j - 1]p[j - 1]。出现此种情况是因为p[j - 1]与对应位置的s[i - 1]相等。

         3.字符‘*’复制k次前一个字符,即p[j - 1] *=p[j - 1]...p[j - 1] (共k次)。出现此种情况是因为p[j - 1]与对应位置的s[i - k + 1]相等。

        elif p[j - 1] == '*':

                if p[j - 2] != s[i - 1] and p[j - 2] != '.':

                        dp[i][j] = dp[i][j - 2]

               else:

                       dp[i][j] = dp[i - 1][j] or dp[i][j - 2]

3)需要注意字符‘*’复制k次的情况,这里的k可以为0:

        dp[i][j] = dp[i - 1][j] or dp[i][j - 2]

另求助以下代码超时,大家能否帮笔者检查修改:

python">class Solution:def isMatch(self, s: str, p: str) -> bool:def dfs(i, j):if i >= len(s) and j >= len(p):return Trueif j >= len(p):return Falsematch = i < len(s) and (s[i] == p[j] or p[j] == '.')if (j + 1) < len(p) and p[j + 1] == '*':return (dfs(i, j + 2) or (match and dfs(i + 1, j)))if match:return dfs(i + 1, j + 1)return Falsereturn dfs(0, 0) 

附上同样运用动态规划的最长公共子序列以及编辑距离的代码实现:

LeetCode in Python 300. Longest Increasing Subsequence (最长递增子序列)-CSDN博客

LeetCode in Python 72. Edit Distance (编辑距离)-CSDN博客


http://www.ppmy.cn/ops/24763.html

相关文章

K8s初次入门

初步:搭建k8s集群 k8s 集群主机清单 主机名ip地址master1.50node-00011.51node-00021.52node-00031.53node-00041.54node-00051.55harbor1.30事先准备 所有的k8s集群主机卸载防火墙和禁用swap交换空间(docker、k8s建议禁用swap) 安装工具 dnf install -y kubeadm kubelet ku…

【算法每日一练】

蛮有意思的的一道题&#xff0c;最后要判断能否成为一种1~n的全排列&#xff0c;我最这样做的&#xff1a; 整个数组先排序一下。假设遍历到了i&#xff0c;那就判断前面b和r的个数&#xff0c;但是有想到了后面可能还会对前面的结果产生影响&#xff0c;所以就抛弃了这个想法…

某音a_bogus导出jsvmp加密函数到全局

记得加入我们的学习群&#xff1a;961566389 点击链接加入群聊&#xff1a;https://h5.qun.qq.com/s/62P0xwrCNO 上一篇文章我们说到s函数不是那么容易导出&#xff0c;但是后面分析&#xff0c;发现虽然他们都叫e函数&#xff0c;但是&#xff0c;每个e函数下面的_v里面的数…

FSNotes for Mac v6.7.1中文激活版:强大的笔记管理工具

FSNotes for Mac是一款功能强大的文本处理与笔记管理工具&#xff0c;为Mac用户提供了一个直观、高效的笔记记录和整理平台。 FSNotes for Mac v6.7.1中文激活版下载 FSNotes支持Markdown语法&#xff0c;使用户能够轻松设置笔记格式并添加链接、图像等元素&#xff0c;实现笔记…

Web3的可持续性:构建环境友好的去中心化系统

引言 随着全球对可持续发展和环境问题的日益关注&#xff0c;Web3技术作为一种新型的互联网模式&#xff0c;也开始受到社区和开发者的关注。但很少有人关注到Web3对环境可持续性的潜在影响。本文将探讨Web3如何构建一个环境友好的去中心化系统&#xff0c;以及这如何促进一个…

2024年CMS市场的份额趋势和使用统计

目前市面上有超过一半的网站都是使用CMS来搭建的&#xff0c;据不完全统计&#xff0c;现在大概有900多种CDM可供选择&#xff0c;以下是最常见的CMS的市场份额和使用率信息&#xff1a; 除了WordPress以外&#xff0c;Shopify和Wix也是比较流行的内容管理系统&#xff0c;尤其…

.NET 面向对象程序设计 —— 设计模式 详细版

1.反射 “到底如何去改良策略模式呢?”小菜恳切地问道。 “你仔细观察过没有,你的代码,不管是用工厂模式写的,还是用策略模式写的,那个分支的 switch 依然去不掉。 原因在哪里?”大鸟反问道。 “因为程序里有下拉选择,用户是有选择的,那么程序就必须要根据用户的选择来…

【JS】找出两个数组中的相同元素与不同元素

一、找出相同元素 &#xff08;1&#xff09;方法一 const filterArr (arr1, arr2) > {let result [];for (let i 0; i < arr1.length; i) {for (let j 0; j < arr2.length; j) {if (arr1[i] arr2[j]) {result.push(arr1[i]);}}}return result; };&#xff08;…