📌  相关文章
📜  门| Sudo GATE 2020 Mock I(2019 年 12 月 27 日)|问题 23(1)

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

题目介绍

本题为 Sudo GATE 2020 Mock I(2019 年 12 月 27 日)中的问题 23。

题目描述如下:

给定一个字符串 s 和一个模式串 p,实现一个函数来判断 s 是否匹配 p。

在匹配中,'?' 可以匹配任何单个字符。'*' 可以匹配任意字符串(包括空字符串)。

示例:

输入:

s = "adcefg" p = "a?c"

输出:

true

输入:

s = "aa" p = "a"

输出:

false

输入:

s = "aa" p = "*"

输出:

true

解题思路

可以使用动态规划来解决这个问题。

我们定义一个二维数组 dp,其中 dp[i][j] 表示 s 的前 i 个字符和 p 的前 j 个字符是否能够匹配。

初始化 dp[0][0] = true,表示空串和空模式串能够匹配。然后我们需要考虑当其中一个字符串为空串时的情况。当 s 为空串时,如果 p 的前 j 个字符都是 '*',那么 dp[0][j] = true;当 p 为空串时,只有当 s 也为空串时,dp[0][0] = true,其它 dp[0][j] = false。

接着,我们考虑转移方程。如果 s 的第 i 个字符和 p 的第 j 个字符能够匹配(即 s[i-1] == p[j-1] 或 p[j-1] == '?'),那么 dp[i][j] = dp[i-1][j-1],否则如果 p[j-1] == '*',那么 dp[i][j] 可以从 dp[i-1][j] 或者 dp[i][j-1] 转移而来。

最终,dp[s.length()][p.length()] 即为题目所求的结果。

代码实现

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 i = 1; i <= n; i++) {
        if (p.charAt(i - 1) == '*') {
            dp[0][i] = true;
        } else {
            break;
        }
    }
    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];
}

总结

本题主要考察了字符串匹配和动态规划的基本思想,需要我们在实际应用中能够熟练掌握。通过题目的解法过程,我们可以更好地理解动态规划的思路,并且能够写出符合要求的代码。