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

题意:

字符串匹配问题,给定一个字串s,一个字串p,在p中 *可以代表任何串(包括空串),?可以代表任意一个字母。

 

解法:

这题看题目第一反应就是用DP方法来做,建立一个表

例如对于 s=abcb   p=a*b

我们可以这样填写一个表

 abcb
TFFFF
aFTFFF
*FTTTT
bFFTFT

 

填写逻辑:

首先 array[0][0]填入True,因为s,p都为空的情况下,可以匹配,之后第0行其余都为False

再看第1行,[1][0] 除非p的第一个是*(只有*可以匹配空),填入T,否则为F;这里p第一个是a,所以array[1][0]=F

之后看[1][1]  因为a==a,再看[i-1][j-1]=[0][0]=T  ,所以array[1][1]=T 之后根据逻辑都填为F,之后的逻辑也大概类似

最后的结果在右下角

 

主要大的两个判断条件:

1.如果p当前字段是*

我们需要看上一行是否有T,如果上一行有T(则说明前面有匹配存在),则该行之后的字段都可以填入T

2.如果p当前字段不是*

我们需要查看(1)[i-1][j-1]是否为T,(2)当前p的字段与s的字段相等,(3)p的字母为?

代码:

class Solution {
    public boolean isMatch(String s, String p) {
        int sL = s.length(), pL = p.length();
    
        boolean[][] dp = new boolean[pL+1][sL+1];
        dp[0][0] = true;

        for(int i=1; i<=pL; i++) {
            boolean flag = false; // The flag check above row T
            char c = p.charAt(i-1);
            for(int j=0; j<=sL; j++) {
                flag = flag || dp[i-1][j];
                if(c != '*') {
                    dp[i][j] = j>0 && dp[i-1][j-1] && (c=='?' || c==s.charAt(j-1));
                }
                else {
                    // For k>=0 and k<=j, if any dp[i-1][k] is true,
                    // then '*' will match the rest sequence in s after index k;
                    dp[i][j] = i==1 || flag;
                }
            }
        }

        return dp[pL][sL];
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值