【题目】
给你一个输入字符串 (s) 和一个字符模式 (p) ,请你实现一个支持 '?' 和 '*' 匹配规则的通配符匹配:
'?'可以匹配任何单个字符。'*'可以匹配任意字符序列(包括空字符序列)。
判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而不是部分匹配)。
示例 1:
输入: s = "aa", p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入: s = "aa", p = "*"
输出: true
解释: '*' 可以匹配任意字符串。
示例 3:
输入: s = "cb", p = "?a"
输出: false
解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。
提示:
0 <= s.length, p.length <= 2000s仅由小写英文字母组成p仅由小写英文字母、'?'或'*'组成
【题目解析】
解题思路
使用贪心算法结合双指针的方法来解决这个问题。主要思路如下:
- 使用两个指针分别遍历输入字符串
s和模式字符串p。 - 当遇到普通字符或
'?'时,如果当前字符匹配,则两个指针都向前移动。 - 遇到
'*'时,记录'*'的位置和当前字符串的匹配位置,然后只移动模式指针。 - 如果遇到不匹配的情况,并且之前遇到过
'*',则回溯到'*'的位置,让'*'多匹配一个字符,然后继续匹配。 - 最后检查模式字符串中剩余的字符是否都是
'*',如果是,则匹配成功。
class Solution:
def isMatch(self, s: str, p: str) -> bool:
# 初始化指针和星号匹配位置
s_idx, p_idx = 0, 0
star_idx = -1
match = 0
# 遍历输入字符串
while s_idx < len(s):
# 匹配单个字符或'?'
if p_idx < len(p) and (p[p_idx] == '?' or p[p_idx] == s[s_idx]):
s_idx += 1
p_idx += 1
# 遇到'*',记录位置,假设'*'匹配空字符串
elif p_idx < len(p) and p[p_idx] == '*':
star_idx = p_idx
match = s_idx
p_idx += 1
# 发现不匹配且之前遇到过'*',回溯,让'*'多匹配一个字符
elif star_idx != -1:
p_idx = star_idx + 1
match += 1
s_idx = match
else:
return False
# 检查模式字符串中剩余的字符是否都是'*'
while p_idx < len(p) and p[p_idx] == '*':
p_idx += 1
return p_idx == len(p)
执行用时
【总结】
适用问题类型
该方法适用于需要灵活匹配模式的字符串处理问题,如通配符匹配、模式识别、路径匹配等。它特别适用于模式中包含可以匹配任意字符序列的通配符(如'*')的情况。
解决算法:贪心算法结合双指针
- 核心思想:通过贪心策略,优先考虑非
'*'字符的匹配,当遇到'*'时,先假设它匹配空字符串,然后根据需要逐步扩展匹配范围。 - 实现细节:使用两个指针分别遍历输入字符串和模式字符串,记录
'*'的位置和当前匹配位置,根据匹配情况动态调整指针位置。
算法特点
- 高效性:避免了不必要的回溯,通过贪心策略和双指针技术实现线性时间复杂度的匹配。
- 灵活性:能够灵活处理包含
'*'和'?'通配符的模式,适应多种匹配需求。 - 简洁性:相比动态规划等其他方法,代码实现更为简洁,易于理解和维护。
算法优化与实践意义
- 优化方向:针对特定场景,可以对算法进行微调,如优化对
'*'的处理逻辑,减少不必要的指针移动。 - 实践意义:该算法在文本处理、编译器构建、网络路由等领域有广泛应用。它提供了一种高效的模式匹配解决方案,能够提高系统的处理性能和响应速度。
总之,贪心算法结合双指针的通配符匹配方法是解决复杂字符串匹配问题的有效工具。它通过简洁的策略实现了高效的匹配过程,适用于多种场景,具有重要的实践价值和应用前景。