📜  门|门 IT 2008 |问题 10(1)

📅  最后修改于: 2023-12-03 15:42:22.193000             🧑  作者: Mango

门|门 IT 2008 | 问题 10

这是一道关于字符串匹配的问题。给定两个字符串s和p,其中s可能包含一些通配符'?'和'','?'匹配任意单个字符,''匹配任意长度的字符。编写一个函数来判断s是否匹配p。

示例
示例 1:

输入:

s = "aa"
p = "a"

输出: false

解释: 'a' 不能匹配到 'aa'。

示例 2:

输入:

s = "aa"
p = "*"

输出: true

解释: '*' 可以匹配任意字符。

示例 3:

输入:

s = "cb"
p = "?a"

输出: false

解释: '?' 数量不够匹配 'b'。

示例 4:

输入:

s = "adceb"
p = "*a*b"

输出: true

解释: '*' 可以匹配 'dce'。

解法

这道题可以用动态规划算法求解。我们定义两个变量i和j,分别表示s和p的当前匹配位置。我们使用一个布尔型二维数组dp,其大小为(len_s+1)×(len_p+1),其中len_s和len_p分别为字符串s和p的长度。dp[i][j]表示s[0:i]是否能被p[0:j]匹配。最终答案为dp[len_s][len_p]。

根据以上定义,我们有以下递推公式:

  1. 当p[j-1]不为'*'时

    如果s[i-1]和p[j-1]匹配,则dp[i][j] = dp[i-1][j-1]。

  2. 当p[j-1]为'*'时

    • 匹配0个字符:dp[i][j] = dp[i][j-1]

    • 匹配1个字符:dp[i][j] = dp[i-1][j-1]

    • 匹配>=1个字符: dp[i][j] = dp[i-1][j]

最后,我们的代码实现需要注意dp数组边角初始值的处理。

代码实现
def isMatch(s: str, p: str) -> bool:
    len_s, len_p = len(s), len(p)
    dp = [[False] * (len_p + 1) for _ in range(len_s + 1)]
    dp[0][0] = True
    for i in range(len_s + 1):
        for j in range(1, len_p + 1):
            if p[j - 1] != '*':
                dp[i][j] = i > 0 and dp[i-1][j-1] and (s[i-1] == p[j-1] or p[j-1] == '?')
            else:
                dp[i][j] = dp[i][j-1] or (i > 0 and dp[i-1][j-1]) or (i > 0 and dp[i-1][j] )

    return dp[len_s][len_p]

以上代码可以在O(N^2)的时间内求解字符串匹配问题,其中N为字符串长度。