LeetCode 44. 通配符匹配---Java题解

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

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

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

说明:

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

示例:

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

输入:
s = "aa"
p = "*"
输出: true
解释: '*' 可以匹配任意字符串。

输入:
s = "cb"
p = "?a"
输出: false
解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。

输入:
s = "adceb"
p = "*a*b"
输出: true
解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".

输入:
s = "acdcb"
p = "a*c?b"
输出: false

基本思想:
动态规划
创建二维数组dp,dp[i][j]表示p串的前i个字符和s串的前j个字符是否匹配。

状态转移方程:
注意p,s下标从0开始
dp[i][j]= dp[i-1][j-1]      p[i-1]=s[i-1] || p[i-1]="?"
dp[i][j]=dp[i-1][j] || dp[i][j-1]    p[i-1]="*"

解释:
当p[i-1]=s[i-1]时,显然第i个字符和第j个字符相等,或者当p[i-1]="?"时,表示当前第i个字符为“?”,表示可以代替任何单个字符,这时前i个和前j个是否匹配就取决于前i-1和前j-1个是否匹配。

当p[i-1]=" * ",题目已经说明, * 可以吃掉任意长的连续字符串, * 就有两种选择:1. * 不吃字符:2. * 吃掉当前字符。

dp[i-1][j]表示 * 不吃掉第j个字符,所以拿前i-1个去匹配前j个。

dp[i][j-1] 表示吃掉当前字符。我用前i个(即最后为 * )去匹配前j-1个,无视第j个,为什么能无视?因为 * 可以吃掉第j个,所以 * 的存在完全可以不用关心第j个字符。为什么是拿前i个字符?因为最后一位的 * 也可能继续匹配第j-1个字符。

初始状态:
dp[0][0]表示空串匹配空串,为true
由于串p开头可能有连续 * ,而 * 可以表示空,前i个都是 * 也可表示空 。假设前i个都是 * ,那么就有dp[0][0]…dp[i][0]都为true。

代码

class Solution {
    
    
    public boolean isMatch(String s, String p) {
    
    
        int m=p.length();
        int n=s.length();

        boolean[][] dp=new boolean[m+1][n+1];
        dp[0][0]=true;//设定初始状态

        char[] sArray=s.toCharArray();
        char[] pArray=p.toCharArray();

        for(int i=1;i<=m;i++){
    
    //p串前连续为*的情况,设定初始态
            if(pArray[i-1]!='*')
                break;
            dp[i][0]=true;
        }

        for(int i=1;i<=m;i++){
    
    
            for(int j=1;j<=n;j++){
    
    
                if(pArray[i-1]==sArray[j-1]||pArray[i-1]=='?')
                //状态转移方程1
                    dp[i][j]=dp[i-1][j-1];
                else if(pArray[i-1]=='*')
                //状态转移方程2
                //第一个为*不匹配当前字符
           		//第二个为*匹配当前字符
                    dp[i][j]=dp[i-1][j]||dp[i][j-1];
            }
        }

        return dp[m][n];
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_44759105/article/details/110295017