菜鸡每日一题系列打卡44天
每天一道算法题目
小伙伴们一起留言打卡
坚持就是胜利,我们一起努力!
题目描述(引自LeetCode)
给定一个字符串s和一个字符模式p,实现一个支持'?'和'*'的通配符匹配。'?'可以匹配任何单个字符。'*'可以匹配任意字符串(包括空字符串)。两个字符串完全匹配才算匹配成功。
说明:
s可能为空,且只包含从a-z的小写字母。
p可能为空,且只包含从a-z的小写字母,以及字符?和*。
示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:
s = "aa"
p = "*"
输出: true
解释: '*' 可以匹配任意字符串。
示例 3:
输入:
s = "cb"
p = "?a"
输出: false
解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。
示例 4:
输入:
s = "adceb"
p = "*a*b"
输出: true
解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".
示例 5:
输入:
s = "acdcb"
p = "a*c?b"
输入: false
题目分析
之前曾写过一道正则表达式匹配的题目,和这道题目类似,当时再求解正则表达式匹配的时候,我们采用的是动态规划的方式,不清楚的小伙伴请移步至文末的相关链接。这道题目也完全可以照搬之前题目的解法。但我们需要思考一下,能不能继续优化,其实,这道题目采用双指针回溯的方式,可以更加节约时间和空间。废话少说,上代码!
代码实现
class Solution {
public boolean isMatch(String s, String p) {
int sp = 0, pp = 0, starp = -1, tmp = -1;
while (sp < s.length()) {
// ?匹配或相等匹配
if (pp < p.length() && (p.charAt(pp) == '?' || p.charAt(pp) == s.charAt(sp))){
sp++;
pp++;
}
// *匹配,从匹配0个字符开始
else if (pp < p.length() && p.charAt(pp) == '*') {
starp = pp++;
tmp = sp;
}
// 回溯至上一个*的下一个位置
else if (starp > -1) {
pp = starp + 1;
sp = ++tmp;
}
// 不匹配
else return false;
}
// 判断p剩余的字符是否都为*
for(int i = pp; i < p.length(); i++){
if (p.charAt(i) != '*') return false;
}
return true;
}
}
代码分析
对代码进行分析,时间复杂度为O(slogp),对时间复杂度的求解过程比较复杂,感兴趣的小伙伴研究一下,在此就不展开。而就空间而言,仅仅使用了常数级别的额外空间,因此,空间复杂度为O(1)。
执行结果
相关链接
其他说明
由于微信公众号的页面模板功能的限制,一个页面模板仅支持保存30篇文章,由于每日一题系列更新已经超过了30篇,因此,菜鸡将其全部归类到每日一题专辑中,在每日一题栏目中仅保存最近更新的30篇,需要翻看历史文章的,可以点击文章顶部的专辑进行查看,其余栏目也可采用该方式查看。如下图所示????。
学习 | 工作 | 分享
????长按关注“有理想的菜鸡”
只有你想不到,没有你学不到