📜  门|门CS 2010 |第 57 题(1)

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

题目描述

门|门CS 2010 年第 57 题是一道经典的字符串匹配问题。给定两个字符串 A 和 B,其中 B 可能包含通配符“*”和“?”,请判断字符串 A 是否与字符串 B 匹配。

解题思路

这个问题可以通过动态规划来解决。我们可以用 dp[i][j] 表示字符串 A 的前 i 个字符和字符串 B 的前 j 个字符是否匹配,其中 i 和 j 分别从 0 开始计数。根据题意,可以得到以下状态转移方程:

  • 如果 A[i-1] 与 B[j-1] 匹配或者 B[j-1] 是“?”,那么 dp[i][j] = dp[i-1][j-1]。
  • 如果 B[j-1] 是“*”,那么 dp[i][j] = dp[i-1][j] || dp[i][j-1]。

最终的结果就是 dp[A.length()][B.length()]。

这道题还需要注意以下几点:

  • dp 数组需要初始化,首先将 dp[0][0] 设为 true,然后对于 A 为空的情况,dp[i][0] 都要设置成 false。
  • 对于 B 中的连续的“”只需要计算一次即可,因为多个“”等效于一个“*”。
  • 时间复杂度为 O(mn)。

代码实现

下面是 Java 代码的实现:

public boolean isMatch(String s, String p) {
    int m = s.length(), n = p.length();
    boolean[][] dp = new boolean[m + 1][n + 1];
    dp[0][0] = true;
    for (int j = 1; j <= n; j++) {
        if (p.charAt(j - 1) == '*') {
            dp[0][j] = dp[0][j - 1];
        }
    }
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= n; j++) {
            if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?') {
                dp[i][j] = dp[i - 1][j - 1];
            } else if (p.charAt(j - 1) == '*') {
                dp[i][j] = dp[i - 1][j] || dp[i][j - 1];
            }
        }
    }
    return dp[m][n];
}

若需要转换为 markdown 格式,请使用 Online convert 等工具。