【LeetCode】No.44. Wildcard Matching -- Java Version

题目链接: https://leetcode.com/problems/wildcard-matching/

1. 题目介绍(Wildcard Matching)

Given an input string (s) and a pattern §, implement wildcard pattern matching with support for ‘?’ and ‘*’ where:

【Translate】: 给定输入字符串(s)和模式( p ),实现通配符模式匹配,并要求支持’?‘和’*’

  • ‘?’ Matches any single character.
  • ‘*’ Matches any sequence of characters (including the empty sequence).

【Translate】: “?”匹配任何单个字符; '*'匹配任何字符序列(包括空序列)。

The matching should cover the entire input string (not partial).

【Translate】: 匹配应该覆盖整个输入字符串(而不是部分)。

【测试用例】:
testcase

【约束】:
constrains

2. 题解

2.1 动态规划

  以s="bbaa", p="*a*a"为例,使用动态规划将通配符匹配的问题划分成一个个小的彼此联系的子问题。我后一个的结果和我前一个的结果或者其它结果之间存在联系。如果我从前面就是错的,那么我就一路错到底。
  该题解来自于DyXrLxSTAOadoD在leetcode_deleted_user的题解 My java DP solution using 2D table中的评论。这种做法为了可读性浪费了很多额外空间。[0][0]那一层其实不是很需要。

我们可以把通配符匹配问题分为以下三种情况:

  1. 当前的p和s字符相同,或者当前p字符为’?’
  2. 当前p字符为’*’
  3. 不符合上述两种条件的其它情况

  第一种情况,如果符合,那么就说明当前通配符匹配的是正确的,那么我当前的结果就可以根据我上一层的结果来看,如果上一层就FALSE了,那么我这一层再对,也没什么用,因为从一开始就是错的;

  第二种情况,如果符合,那么我当前的结果就要看我上一层的结果和我前一个的结果,因为’*'可以匹配所有的串,所以说只要前面不出错,后面我肯定对;

  第三种情况,属于啥都不是,直接FALSE。

demo1

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

case1

2.2 双指针

  该题解来自于pandora111的 Linear runtime and constant space solution,其基本思想是用一个指针指向str,一个指针指向pattern。这个算法最多迭代length(str)+length(pattern)次,对于每次迭代,至少有一个指针向前推进一步。

class Solution {
    public boolean isMatch(String str, String pattern) {
        int s = 0, p = 0, match = 0, starIdx = -1;            
        while (s < str.length()){
            // advancing both pointers
            if (p < pattern.length()  && (pattern.charAt(p) == '?' || str.charAt(s) == pattern.charAt(p))){
                s++;
                p++;
            }
            // * found, only advancing pattern pointer
            else if (p < pattern.length() && pattern.charAt(p) == '*'){
                starIdx = p;
                match = s;
                p++;
            }
           // last pattern pointer was *, advancing string pointer
            else if (starIdx != -1){
                p = starIdx + 1;
                match++;
                s = match;
            }
           //current pattern pointer is not star, last patter pointer was not *
          //characters do not match
            else return false;
        }
        
        //check for remaining characters in pattern
        while (p < pattern.length() && pattern.charAt(p) == '*')
            p++;
        
        return p == pattern.length();
    }
}

case2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TomLazy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值