LeetCode 44 Wildcard Matching (通配符匹配 记忆化搜索 剪枝 推荐)

本文主要是介绍LeetCode 44 Wildcard Matching (通配符匹配 记忆化搜索 剪枝 推荐),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

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

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like ? or *.

Example 1:

Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".

Example 2:

Input:
s = "aa"
p = "*"
Output: true
Explanation: '*' matches any sequence.

Example 3:

Input:
s = "cb"
p = "?a"
Output: false
Explanation: '?' matches 'c', but the second letter is 'a', which does not match 'b'.

Example 4:

Input:
s = "adceb"
p = "*a*b"
Output: true
Explanation: The first '*' matches the empty sequence, while the second '*' matches the substring "dce".

Example 5:

Input:
s = "acdcb"
p = "a*c?b"
Output: false

题目链接:https://leetcode.com/problems/wildcard-matching/

题目分析:与正则匹配比较类似,本题不用记忆化会直接超时,多个连续的'*'可直接缩成1个,功能不会产生变化

25ms,时间击败76.9% (运行时间不是很稳定,21ms~28ms)

class Solution {public boolean isFirstPosMatch(String s, int spos, String p, int ppos) {return (spos < s.length() &&(s.charAt(spos) == p.charAt(ppos) ||p.charAt(ppos) == '?'));}public boolean isMatch(String s, String p) {int[][] match = new int[s.length() + 2][p.length() + 2];return isMatchHelper(s, 0, p, 0, match);}public boolean isMatchHelper(String s, int spos, String p, int ppos, int[][] match) {if (match[spos][ppos] != 0) {return match[spos][ppos] == 1;}if (ppos == p.length()) {match[spos][ppos] = spos == s.length() ? 1 : -1;return match[spos][ppos] == 1;}if (p.charAt(ppos) != '*') {match[spos][ppos] = isFirstPosMatch(s, spos, p, ppos) && isMatchHelper(s, spos + 1, p, ppos + 1, match) ? 1 : -1;return match[spos][ppos] == 1;}while (ppos < p.length() && p.charAt(ppos) == '*') {ppos++;}while (spos < s.length()) {match[spos][ppos] = isMatchHelper(s, spos, p, ppos, match) ? 1 : -1;if (match[spos][ppos] == 1) {return true;}spos++;}match[spos][ppos] = isMatchHelper(s, spos, p, ppos, match) ? 1 : -1;return match[spos][ppos] == 1;}
}

最后的while循环看上去是比较耗时的,可以从中挖掘一些剪枝,通配符匹配和正则匹配的一大不同就是通配符匹配中模式串的确定字符必须要在主串上严格匹配(正则可通过'*'消去前一项),于是想到用两个cnt数组分别记录s和p中字符串的个数,设当前匹配到了s的第i项s[i],若pcnt[s[i]] > scnt[s[i]],则说明s串接下来的s[i]字符已不够p串匹配了,故此时的'*'不能消掉s[i]

加了这个剪枝后,6ms,时间击败97.9%

class Solution {public boolean isFirstPosMatch(String s, int spos, String p, int ppos) {return (spos < s.length() &&(s.charAt(spos) == p.charAt(ppos) ||p.charAt(ppos) == '?'));}public boolean isMatch(String s, String p) {int[] scnt = new int[26];int[] pcnt = new int[26];for (int i = 0; i < s.length(); i++) {scnt[s.charAt(i) - 'a']++;}for (int i = 0; i < p.length(); i++) {char ch = p.charAt(i);if (ch >= 'a' && ch <= 'z') {pcnt[ch - 'a']++;}}int[][] match = new int[s.length() + 2][p.length() + 2];return isMatchHelper(s, 0, p, 0, match, scnt, pcnt);}public boolean isMatchHelper(String s, int spos, String p, int ppos, int[][] match, int[] scnt, int[] pcnt) {if (match[spos][ppos] != 0) {return match[spos][ppos] == 1;}if (ppos == p.length()) {match[spos][ppos] = spos == s.length() ? 1 : -1;return match[spos][ppos] == 1;}if (p.charAt(ppos) != '*') {boolean ok = isFirstPosMatch(s, spos, p, ppos);if (ok) {scnt[s.charAt(spos) - 'a']--;if (p.charAt(ppos) != '?') {pcnt[p.charAt(ppos) - 'a']--;}ok &= isMatchHelper(s, spos + 1, p, ppos + 1, match, scnt, pcnt);if (p.charAt(ppos) != '?') {pcnt[p.charAt(ppos) - 'a']++;}scnt[s.charAt(spos) - 'a']++;}match[spos][ppos] = ok ? 1 : -1;return ok;}while (ppos < p.length() && p.charAt(ppos) == '*') {ppos++;}while (spos < s.length() && pcnt[s.charAt(spos) - 'a'] <= scnt[s.charAt(spos) - 'a']) {match[spos][ppos] = isMatchHelper(s, spos, p, ppos, match, scnt, pcnt) ? 1 : -1;if (match[spos][ppos] == 1) {return true;}scnt[s.charAt(spos) - 'a']--;   spos++;}match[spos][ppos] = isMatchHelper(s, spos, p, ppos, match, scnt, pcnt) ? 1 : -1;return match[spos][ppos] == 1;}
}

 

这篇关于LeetCode 44 Wildcard Matching (通配符匹配 记忆化搜索 剪枝 推荐)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/829469

相关文章

浅谈配置MMCV环境,解决报错,版本不匹配问题

《浅谈配置MMCV环境,解决报错,版本不匹配问题》:本文主要介绍浅谈配置MMCV环境,解决报错,版本不匹配问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录配置MMCV环境,解决报错,版本不匹配错误示例正确示例总结配置MMCV环境,解决报错,版本不匹配在col

详解nginx 中location和 proxy_pass的匹配规则

《详解nginx中location和proxy_pass的匹配规则》location是Nginx中用来匹配客户端请求URI的指令,决定如何处理特定路径的请求,它定义了请求的路由规则,后续的配置(如... 目录location 的作用语法示例:location /www.chinasem.cntestproxy

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

查看Oracle数据库中UNDO表空间的使用情况(最新推荐)

《查看Oracle数据库中UNDO表空间的使用情况(最新推荐)》Oracle数据库中查看UNDO表空间使用情况的4种方法:DBA_TABLESPACES和DBA_DATA_FILES提供基本信息,V$... 目录1. 通过 DBjavascriptA_TABLESPACES 和 DBA_DATA_FILES

最新Spring Security实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)

《最新SpringSecurity实战教程之表单登录定制到处理逻辑的深度改造(最新推荐)》本章节介绍了如何通过SpringSecurity实现从配置自定义登录页面、表单登录处理逻辑的配置,并简单模拟... 目录前言改造准备开始登录页改造自定义用户名密码登陆成功失败跳转问题自定义登出前后端分离适配方案结语前言

OpenManus本地部署实战亲测有效完全免费(最新推荐)

《OpenManus本地部署实战亲测有效完全免费(最新推荐)》文章介绍了如何在本地部署OpenManus大语言模型,包括环境搭建、LLM编程接口配置和测试步骤,本文给大家讲解的非常详细,感兴趣的朋友一... 目录1.概况2.环境搭建2.1安装miniconda或者anaconda2.2 LLM编程接口配置2

Python使用DeepSeek进行联网搜索功能详解

《Python使用DeepSeek进行联网搜索功能详解》Python作为一种非常流行的编程语言,结合DeepSeek这一高性能的深度学习工具包,可以方便地处理各种深度学习任务,本文将介绍一下如何使用P... 目录一、环境准备与依赖安装二、DeepSeek简介三、联网搜索与数据集准备四、实践示例:图像分类1.

Redis 内存淘汰策略深度解析(最新推荐)

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand... 目录一、 内存淘汰策略概述二、内存淘汰策略详解2.1 ​noeviction(不淘汰)​2.2 ​LR

Nginx中location实现多条件匹配的方法详解

《Nginx中location实现多条件匹配的方法详解》在Nginx中,location指令用于匹配请求的URI,虽然location本身是基于单一匹配规则的,但可以通过多种方式实现多个条件的匹配逻辑... 目录1. 概述2. 实现多条件匹配的方式2.1 使用多个 location 块2.2 使用正则表达式

Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)

《Vue项目的甘特图组件之dhtmlx-gantt使用教程和实现效果展示(推荐)》文章介绍了如何使用dhtmlx-gantt组件来实现公司的甘特图需求,并提供了一个简单的Vue组件示例,文章还分享了一... 目录一、首先 npm 安装插件二、创建一个vue组件三、业务页面内 引用自定义组件:四、dhtmlx