【LeetCode】44.Wildcard Matching

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_26440803/article/details/80686141

这个道题的大意是:输入一个目标串:s ,以及一个匹配串:p,进行如下规则的匹配:
如果p中存在?,则可以匹配s中任意一个单个字符
如果p中存在*,则可以匹配s中任意一串连续的序列,包括空字符

解法一:双指针

给定两个指针pIndex,sIndex。一个遍历p一个遍历s。当我们遍历时,会遇见如下的情况:

  1. 当s[pIndex] == s[sIndex] 或者 p[Index] == ‘?’ 时,我们可以直接对pIndex,sIndex 进行前移位操作。
  2. 如果当p[pIndex] =='*' 时,我们需要做如下操作:pIndex向后移位,重复(1)操作,因为我们的*有可能匹配的是空,当然,我们还需要记录下这个pIndex位置与匹配s串中失败的那个位置点match ,因为我们不知道当前位置的*匹配是否是正确的,因为当*只有后面一位与s进行匹配成功,而其他的不匹配则说明我们的*匹配s串的位置不对(即使这里*后面一位与上面的s匹配成功)。
  3. 当操作2失败后,我们应该回溯,通过上面记录的*的位置,我们从*下一个位置与match 下一个位置继续进行(1)操作。
  4. 判断pIndex 是否走完。
public static boolean isMatch(String str,String  pattern) {
        int s = 0, p = 0,match = 0,startIdx = -1;
        while(s<str.length()) {
            if(p<pattern.length() && (pattern.charAt(p) == '?' || str.charAt(s) == pattern.charAt(p))) {
                s++;p++;
            }else if(p<pattern.length() && pattern.charAt(p) == '*') {
                startIdx = p;
                match = s;
                p++;
            }else if(startIdx != -1) {
                p = startIdx +1;
                match++;
                s = match;
            }else {
                return false;
            }
        }
        while(p < pattern.length() && pattern.charAt(p) == '*') {
            p++;
        }
        return  p == pattern.length();
    }

解法二:DP

通过分析可以得出如下的递归关系公式:

这里写图片描述

这里的i,j分别代表s中的j位置与p中的i位置是否匹配。利用DP,我们可以将问题的规模不断缩小、。
如果当pattern.charAt(j-1) == str.charAt(i-1) || pattern.charAt(j-1) == '?'那么证明s[j] == p[i],我们只需要关心s[i-1] == s[j-1]就可以了。成功将问题规模缩小。
如果当p[i]=='*''*'匹配0个字符,dp[i][j]=dp[i-1][j];匹配1个字符,dp[i][j]=dp[i-1][j-1]所以,
dp[i][j]=dp[i-1][j]||dp[i-1][j-1]||……||dp[i-1][0]
但是上面的公式可以化简,当p.charAt(i)=='*'时,有
dp[i][j-1]=dp[i-1][j-1]||dp[i-1][j-2]||……||dp[i-1][0]
成功转换为:
dp[i][j] = dp[i-1][j] || dp[i][j-1].

public static boolean isMatchDP(String str,String pattern) {
        int  sLen = str.length();
        int  lLen = pattern.length();
        boolean[][] dp = new boolean[sLen+1][lLen+1];
        dp[0][0] = true;
        for(int i=1;i<=lLen;i++) {
            dp[0][i] = dp[0][i-1] && pattern.charAt(i-1) == '*';
        }

        for(int i=1; i<= sLen;i++) {
            for(int j=1; j <= lLen ;j++) {
                if(pattern.charAt(j-1) == str.charAt(i-1) || pattern.charAt(j-1) == '?') {
                    dp[i][j] = dp[i-1][j-1];
                }else if(pattern.charAt(j-1) == '*'){
                    dp[i][j] = dp[i-1][j] || dp[i][j-1];
                }
            }
        }
        return dp[sLen][lLen];
    }

猜你喜欢

转载自blog.csdn.net/qq_26440803/article/details/80686141