[LeetCode] 44、通配符匹配

白昼怎懂夜的黑 提交于 2019-12-09 20:10:22

题目描述

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

‘?’ 可以匹配任何单个字符。
‘*’ 可以匹配任意字符串(包括空字符串)。

两个字符串完全匹配才算匹配成功。

说明:

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

示例:

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

解题思路

此题模仿《剑指offer》的递归写法,会超时。要用动态规划。思路1思路2

动态规划四要素:(推荐思路1的解释,思路2某些点不清晰)

  • 状态表示

    • f[i][j]f[i][j]表示s1s1的前ii个字符,和s2s2的前jj​个字符,能否匹配。(下标从1开始计)
  • 状态转移方程

    • 如果s1s1的第ii 个字符和s2s2的第 jj 个字符相同,或者s2s2的第 jj 个字符为 ?'?'f[i][j]=f[i1][j1]f[i][j] = f[i - 1][j - 1]

    • 如果s2s2​的第 jj​ 个字符为 '*'​

      • s2s2​的第 jj​ 个字符匹配空串:f[i][j]=f[i][j1]f[i][j] = f[i][j - 1]​,例如ab,ab*

      • s2s2​的第 jj​ 个字符匹配s1s1​的第 ii​ 个字符: f[i][j]=f[i1][j]f[i][j] = f[i - 1][j]​,例如abcd,ab*

        注意:这里这不是 f[i1][j1]f[i - 1][j - 1]​, 举个例子就明白了​。

  • 初始化

    • f[0][i]=(f[0][i1] && s2[i]==)f[0][i] = (f[0][i - 1]\ \&\&\ s2[i] == *)​
    • s1s1​的前00​个字符和s2s2​的前ii​个字符能否匹配
    • 换个思路理解:
      • dp[0][0]:什么都没有,所以为true
      • 第一行dp[0][j],换句话说,s为空,与p匹配,所以只要p开始为*才为true
      • 第一列dp[i][0],当然全部为False
  • 结果

    • f[m][n]f[m][n]​

参考代码

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.length();
        int n = p.length();
        if(m == 0 && n == 0)
            return true;
        if(n == 0)
            return false;
        
        // 此题必须设置为dp[m+1][n+1]
        bool dp[m+1][n+1];
        memset(dp, 0, m*n);
        dp[0][0] = true;
        for(int j = 1; j < n; j++)
            dp[0][j] = dp[0][j-1] && p[j] == '*';
        
        for(int i = 1; i <= m; i++){
            for(int j = 1; j <= n; j++){
                if(s[i-1] == p[j-1] || p[j-1] == '?')
                    dp[i][j] = dp[i-1][j-1];
                
                if(p[j-1] == '*')
                    dp[i][j] = dp[i][j-1] || dp[i-1][j];
                
            }
        }
        
        return dp[m][n];
    }
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!