每日一题——通配符匹配

菜鸡每日一题系列打卡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篇,需要翻看历史文章的,可以点击文章顶部的专辑进行查看,其余栏目也可采用该方式查看。如下图所示????。

学习 | 工作 | 分享

????长按关注“有理想的菜鸡

只有你想不到,没有你学不到

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值