思路及解答递归
如果pattern ⻓度为0且str ⻓度为0 ,说明刚刚好匹配完返回turestr ⻓度不为0 说明没有匹配完返回false如果pattern 的⻓度⼤于0如果pattern 的⻓度⼤于1 且第2 个字符是* 说明前⾯的字符可以匹配0 1 或者多次分为两种情况讨论⼀种是直接把* 和* 前⾯的字符去掉相当于匹配了0 个然后接着⽐较另外⼀种是如果str 的⻓度⼤于0 并且第⼀个字符匹配那就把str 的第⼀个字符去掉两者接着匹配。否则说明第⼆个字符不是 * 那么就直接⽐较第⼀个字符是不是匹配同时将后⾯的字符进⾏匹配。注意上⾯说的第⼀个字符是不是匹配除了两个字符相等的情况其实还有模式串的字符为 . 的情况。javapublic class Solution { public boolean isMatch(String s, String p) { // 模式串为空时文本串也必须为空才匹配 if (p.isEmpty()) return s.isEmpty(); // 检查首字符匹配文本串非空且字符相等或模式为. boolean firstMatch !s.isEmpty() (s.charAt(0) p.charAt(0) || p.charAt(0) .); // 处理*通配符确保模式长度≥2且第二个字符是* if (p.length() 2 p.charAt(1) *) { // 两种情况1) *匹配0个前驱字符 2) 匹配1个及以上前驱字符 return isMatch(s, p.substring(2)) || (firstMatch isMatch(s.substring(1), p)); } else { // 无*情况首字符匹配且剩余部分也匹配 return firstMatch isMatch(s.substring(1), p.substring(1)); } } }时间复杂度最坏O((mn)2^(mn))空间复杂度O(m²n²)递归栈记忆化搜索递归缓存在递归基础上添加缓存避免重复计算。使用二维数组存储s[i:]和p[j:]的匹配结果避免重复递归javapublic class Solution { private Boolean[][] memo; // 缓存数组null未计算true/false已计算 public boolean isMatch(String s, String p) { memo new Boolean[s.length() 1][p.length() 1]; return dfs(0, 0, s, p); } private boolean dfs(int i, int j, String s, String p) { // 检查缓存是否存在当前子问题的解 if (memo[i][j] ! null) return memo[i][j]; boolean result; // 模式串耗尽时文本串也必须耗尽 if (j p.length()) { result (i s.length()); } else { // 计算当前首字符匹配状态 boolean firstMatch (i s.length()) (s.charAt(i) p.charAt(j) || p.charAt(j) .); // 处理*通配符 if (j 1 p.length() p.charAt(j 1) *) { result dfs(i, j 2, s, p) || // 匹配0次 (firstMatch dfs(i 1, j, s, p)); // 匹配1次 } else { result firstMatch dfs(i 1, j 1, s, p); } } memo[i][j] result; // 存储结果到缓存 return result; } }时间复杂度O(m×n)空间复杂度O(m×n)动态规划推荐动态规划⾸先定义状态⽤⼀个⼆维数组套路dp[i][j]⽤来表示str 的前i 个字符和pattern 的前j 个字符是否匹配。初始化简单状态dp[0][0] true,表示两个空的字符串是匹配的。dp 数组的⾸列除了dp[0][0] 为true其他的都是false 。因为pattern 为空但是s 不为空的时候肯定不匹配。dp 的⾸⾏也就是str 为空的时候如果pattern 的偶数位都是“*”,那么就可以匹配因为可以选择匹配0 次。初始化前⾯之后后⾯的从索引1 开始匹配pattern 的第j 个字符为“ * ”(即是pattern[j-1]*)如果dp[i][j-2]true那么dp[i][j]true(相当于str的前i和pattern的前j-2个字符匹配此时的* 前⾯的那个字符出现了0 次)。如果dp[i-1][j]true且str[i-1]pattern[j-2]则dp[i][j] true。如果str 的前i - 1 个字符和pattern 的前j 个字符匹配并且str 的第i 个字符和pattern 的第j - 1 个字符相等,相当于‘ * ’前⾯的字符出现了1 次如果dp[i-1][j]true且pattern[j-2].的时候则dp[i][j]true。(表示str 的前i-1 个和patten 的前j 个匹配并且pattern 的第j-1 个是‘ . ’第j 个是‘ * ’,那么说明可以匹配任何字符任何次数⾃然str 可以多匹配⼀个字符。)pattern 的第j 个字符不为“ * ”(即是pattern[j-1]*)如果dp[i - 1][j - 1]true and str[i - 1] pattern[j - 1]时则dp[i][j]true。也就是前⾯匹配接下来的字符⼀样匹配如果dp[i - 1][j - 1]true且pattern[i-1].那么dp[i][j]true。(其实也是. 可以匹配任何字符)处理完数组之后最后返回dp[n-1][m-1]也就是str 的前n 个和pattern 的前m 个字符是否匹配。javapublic boolean match(String str, String pattern) { if (pattern.length() 0) { return str.length() 0; } int n str.length() 1; int m pattern.length() 1; boolean[][] dp new boolean[n][m]; dp[0][0] true; for (int j 2; j m; j j 2) { if (dp[0][j - 2] pattern.charAt(j - 1) *) { dp[0][j] true; } } for (int i 1; i n; i) { for (int j 1; j m; j) { if (pattern.charAt(j - 1) *) { dp[i][j] dp[i][j - 2] || dp[i - 1][j] (str.charAt(i - 1) pattern.charAt(j - 2) || pattern.charAt(j - 2) .); } else { dp[i][j] dp[i - 1][j - 1] (str.charAt(i - 1) pattern.charAt(j - 1) || pattern.charAt(j - 1) .); } } } return dp[n - 1][m - 1]; }时间复杂度 O(mn) 其中 m , n 分别为 str 和 pattern 的⻓度状态转移需遍历整个 dp 矩阵。空间复杂度 O(mn) 状态矩阵 dp 使⽤ O(mn) 的额外空间。状态机优化空间优化DP状态机优化滚动数组降低空间复杂度只保留当前行和上一行的状态空间优化到O(n)javapublic class Solution { public boolean isMatch(String s, String p) { int m s.length(), n p.length(); boolean[] dp new boolean[n 1]; boolean[] prev new boolean[n 1]; // 初始化第一行空文本串情况 dp[0] true; for (int j 2; j n; j) { if (p.charAt(j - 1) *) { dp[j] dp[j - 2]; } } for (int i 1; i m; i) { // 保存上一行状态 boolean[] temp prev; prev dp; dp temp; // 初始化当前行首列 dp[0] false; for (int j 1; j n; j) { char sc s.charAt(i - 1); char pc p.charAt(j - 1); if (pc *) { char prevChar p.charAt(j - 2); boolean matchZero dp[j - 2]; boolean matchMulti (prevChar sc || prevChar .) prev[j]; dp[j] matchZero || matchMulti; } else { dp[j] (pc . || pc sc) prev[j - 1]; } } } return dp[n];

相关新闻

WRF一个月模拟不跑偏?试试用ERA5数据开启Grid Nudging(附namelist.input避坑配置)

WRF一个月模拟不跑偏?试试用ERA5数据开启Grid Nudging(附namelist.input避坑配置)

WRF中短期模拟稳定性实战:ERA5数据与Grid Nudging的精准调控策略当你在进行为期数周的WRF模拟时,是否遇到过模拟结果逐渐偏离再分析场的困扰?这种"跑偏"现象在中短期模拟中尤为常见,而Grid Nudging技术正是解决这一问题…

2026/7/1 6:12:26阅读更多 →
哑铃图:数据对比的优雅之选合集 - 数据可视化(66)

哑铃图:数据对比的优雅之选合集 - 数据可视化(66)

哑铃图是什么?哑铃图(Dumbbell Plot),有时也称为DNA图或杠铃图,是一种用于比较两个相关数据点的可视化图表。它源于人们对更有效数据比较方式的持续探索。在传统的时间序列比较中,我们通常使用两条折线&…

2026/7/1 6:07:25阅读更多 →
SAP PS模块实战:手把手教你用BAPI批量创建WBS和项目(附透明表查询技巧)

SAP PS模块实战:手把手教你用BAPI批量创建WBS和项目(附透明表查询技巧)

SAP PS模块实战:BAPI批量创建WBS与透明表查询全攻略在装备制造和能源工程这类大型项目中,手动逐个创建WBS元素就像用勺子挖运河——理论上可行,但实操中会让你怀疑人生。作为经历过数十个SAP PS模块实施的顾问,我总结出一套高效可…

2026/7/1 6:07:25阅读更多 →
别再乱设torch.backends.cudnn了!PyTorch炼丹师必懂的benchmark与deterministic实战避坑指南

别再乱设torch.backends.cudnn了!PyTorch炼丹师必懂的benchmark与deterministic实战避坑指南

PyTorch性能优化与结果复现:深入解析cudnn.benchmark与deterministic的黄金法则在深度学习项目的实际开发中,我们常常面临两个看似矛盾的核心需求:训练速度的最大化和实验结果的完全可复现。这两个需求背后,隐藏着PyTorch框架中两…

2026/7/1 7:13:15阅读更多 →
PromptSRC论文精读:我们是如何让提示学习不再‘过拟合’的?

PromptSRC论文精读:我们是如何让提示学习不再‘过拟合’的?

PromptSRC:如何通过自调节机制突破提示学习的泛化瓶颈当CLIP等视觉语言模型展现出惊人的zero-shot能力时,研究者们很快发现了一个悖论:传统的提示学习方法在提升下游任务表现的同时,往往会以牺牲模型原有的泛化能力为代价。这种现…

2026/7/1 7:13:15阅读更多 →
信创 数据库软件转型

信创 数据库软件转型

数据库软件很多要替换成信创的,所以dba也要跟着转型

2026/7/1 7:13:15阅读更多 →
JMeter分布式压测环境搭建与性能调优实战指南

JMeter分布式压测环境搭建与性能调优实战指南

1. 项目概述:为什么需要分布式压测?做性能测试的朋友,尤其是用过JMeter的,肯定都遇到过单机瓶颈。你兴致勃勃地写好了脚本,模拟了复杂的业务场景,准备大干一场,结果一跑起来,自己的电…

2026/7/1 7:13:15阅读更多 →
告别灾难性遗忘:用PromptSRC让CLIP模型学会新技能,不忘老本行

告别灾难性遗忘:用PromptSRC让CLIP模型学会新技能,不忘老本行

突破灾难性遗忘:PromptSRC如何让CLIP模型实现技能叠加在人工智能领域,视觉语言模型(如CLIP)已经展现出令人惊叹的跨模态理解能力。然而,当工程师们尝试将这些基础模型适配到具体下游任务时,往往会遭遇一个棘…

2026/7/1 7:13:14阅读更多 →
Qt的技巧笔记(一):Qt的QComboBox与自定义的枚举类型的遍历绑定

Qt的技巧笔记(一):Qt的QComboBox与自定义的枚举类型的遍历绑定

步骤1:定义枚举首先,定义你的枚举,通常这会在一个类中完成例如:class MyClass : public QObject {Q_OBJECTpublic:enum MyEnum {Value1,Value2,Value3};Q_ENUM(MyEnum) // 告诉Qt的元对象系统这是一个枚举 };其中,Q_EN…

2026/7/1 7:08:14阅读更多 →
AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

AI Coding 六个月真实ROI账本:产品经理的血泪教训,研发的冷静忠告

6个月前的2025年12月,Boris Cherny 公开宣布自己卸载了 IDE。一时间,Vibe Coding 成了全行业最热的话题。6个月后,当我们回过头来拉一份真实账本,发现事情远没有"一句话生成一个App"那么浪漫。本文从产品经理和研发两个…

2026/7/1 4:42:14阅读更多 →
审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

审计来了,数据权限全开——审计走了,怎么确保权限全部关掉?

引言:审计结束三个月了,审计员的权限还没关某城商行每年按照监管要求开展至少一次数据安全审计。审计期间,内审部门需要抽样检查各类业务数据——交易流水、客户信息、员工操作日志、权限配置记录。这些数据分布在不同系统中,审计…

2026/7/1 5:19:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/1 0:01:44阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/1 0:01:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/1 0:01:44阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/1 0:01:44阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/1 0:01:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/1 0:01:44阅读更多 →