Leetcode 44: 通配符匹配 (Wildcard Matching)

leetcode 44 通配符匹配

题目链接

题目的👍数:2041
题目的👎数:117

1. 问题描述:

给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。

'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。
两个字符串完全匹配才算匹配成功。

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。
示例 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。

2、方法:动态规划

这类 字符串的问题比较容易想到使用动态规划,此时需要考虑状态如何转换,有两个字符串,通常考虑考虑定义二维数组dp[i][j]表示,第一个字符串的前i个字符与第二个字符串的前j个字符是否能够匹配,定义之后不难想到状态转移方程

  1. p[j] 为 ‘?’ 时,s[i]与p[j]匹配,则只需要考虑dp[i-1][j-1]
  2. s[i] == p[j] 时,同上
  3. p[j] == ‘*’ 时,考虑两种情况:如果代表了空字符串,则 dp[i][j] = dp[i][j-1];如果不为空字符串,可以代表任意一段字符串,也就是说只要任意dp[k][j-1]成立(k属于 [0,i-1]),dp[i][j]就成立 。那么怎么知道dp[k][j-1]是否成立呢?如果再次循环k的话时间复杂度过高,这里可以考虑两种方法:1)使用一个flag记录遍历j-1时是否会有成立的情况 2)直接考虑 dp[i][j] = dp[i-1][j],因为计算dp[i-1][j]时又会考虑考虑dp[i-2][j]的成立,所以能找到一个dp[k][j]成立的话,就会使之后的所有dp[i][j]成立。
  4. 动态规划的题(一维或者二维)可以画出图标便于理解

s="abcde" p="*a*b"为例

0*a*b
0TTFFF
aFTTTF
bFTFTT
cFTFTF
dFTFTF
eFTFTF

3、代码

class Solution {
    public boolean isMatch(String s, String p) {
        return helperByDp(s,p);
    }

    public boolean helperByDp(String s1,String s2) {
        int l1 = s1.length();
        int l2 = s2.length();
        boolean[][] dp = new boolean[l1+1][l2+1];
        for(int i = 1;i<=l2;++i) {
            if(s2.charAt(i-1) == '*') dp[0][i] = true;
            else break;
        }
        dp[0][0] = true;
        for(int i = 1;i<=l1;++i) {
            for(int j = 1;j<=l2;++j) {
                if(s2.charAt(j-1) == '*') {
                    dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
                } else if(s2.charAt(j-1) == '?') {
                    dp[i][j] = dp[i-1][j-1];
                } else if(s1.charAt(i-1) == s2.charAt(j-1)) {
                    dp[i][j] = dp[i-1][j-1];
                }
            }
        }
        return dp[l1][l2];
    } 
}

4、复杂度

  1. 时间复杂度 :二重循环 O(n2)
  2. 空间复杂度:二维数组 O(n2)
    在这里插入图片描述
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值