题目:通配符匹配

难度:hard

题目内容

Given an input string (s) and a pattern (p), implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

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

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like ? or *.

翻译:给定一个输入字符串(s)和一个模版(p),实现通配符模式匹配,并支持“?””和“*”。

”?匹配任何一个字符。

“匹配任何字符序列(包括空序列)。

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

 

注意:

s可以是空的,并且只包含小写字母a-z。

p可以是空的,只包含小写字母a-z,还有?或*。

我的思路:此题和第10题很像:Regular Expression Matching,但是10题里是' . '和 ' * ',这里是' ? ' 和 ‘ * ’,

' . '和 ' ? ' 意义相对应,但是  ' * ' 表示意义不同,第10题是只代表个数,本题是代表任何序列,于是把第十题代码修改下:

1、first_match要加上 pattern.charAt(0) == '*' 的情况;

2、后面分两种互斥情况A、B:

A:以 * 匹配:(此时又分两种相容情况)

   a1:*没有匹配任何的字符

   a2:*匹配上此字符

  A情况的结果为  a1 || a2

B:没*:

  当前匹配结果 && 下一个元素和下一个pattern的匹配结果。

我的代码:

     public boolean isMatch(String text, String pattern) {
if (pattern.isEmpty()) return text.isEmpty();
boolean first_match = (!text.isEmpty() &&
(pattern.charAt(0) == text.charAt(0) || pattern.charAt(0) == '?' || pattern.charAt(0) == '*')); if (pattern.charAt(0) == '*'){
return (isMatch(text, pattern.substring(1)) ||
(isMatch(text.substring(1), pattern)));
} else {
return first_match && isMatch(text.substring(1), pattern.substring(1));
}
}

结果:1614 / 1808 test cases passed.

Last executed input:   "aaabbbaabaaaaababaabaaabbabbbbbbbbaabababbabbbaaaaba"   "a*******b"

------Time Limit Exceeded------

看来那个方法是可行的,可能是因为用了递归,中间太多***导致子递归太多,所以运行太慢。

答案代码

     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];
}

答案复杂度:O(M*N)

答案思路:使用一个二维数组对每个点的匹配状态进行记录,后面点的匹配状态取决于当前匹配和之前匹配,所以最后一个点的匹配状态就是整个匹配结果。

数组的行列分别为pattern,str

算法主要分两部分:

1、给第0行和第0列赋值:

  第0列——除了第一个为true以外都为默认值false;

  第0行——如果pattern某个位置为*,则此时对应第0行的值等于前面一个的值,否则取默认值false。

2、从第第1行第1列的元素开始:

  如果当前str值与pattern的值直接匹配上(或者匹配?)则二维数组此值直接取上一个“元素”的匹配结果:【i-1】【j-1】

  如果当前str值与pattern的值是靠‘’*‘’才匹配上,则二维数组此值等于

    (*没有匹配上此字符 || *匹配上此字符)==(这个元素和上一个pattern结果 || 这一个pattern和上一个元素的结果)

  以上两者都不是,则取默认值false

eg. pattern = *a**a    str = bbaa

bp[][]=   ' '       *      a       *      *       a

'' [true, true, false, false, false, false]
b [false, true, false, false, false, false]
b [false, true, false, false, false, false]
a [false, true, true, true, true, false]
a [false, true, true, true, true, true]

结论:第二种(答案)方法虽然不错,但是理解起来太麻烦,不过也很好记,记住思路也行。。。

   在一般的面试或者笔试中使用第一种(我写的)方法足以应对。

LeetCode第[44]题(Java):Wildcard Matching的更多相关文章

  1. LeetCode第[18]题(Java):4Sum 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + ...

  2. LeetCode第[1]题(Java):Two Sum 标签:Array

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  3. LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2

    题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...

  4. LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  5. [Leetcode 44]通配符匹配Wildcard Matching

    [题目] 匹配通配符*,?,DP动态规划,重点是*的两种情况 想象成两个S.P长度的字符串,P匹配S. S中不会出现通配符. [条件] (1)P=null,S=null,TRUE (2)P=null, ...

  6. LeetCode第[10]题(Java):Regular Expression Matching

    题目:匹配正则表达式 题目难度:hard 题目内容:Implement regular expression matching with support for '.' and '*'. '.' Ma ...

  7. leetcode第十题--Regular Expression Matching

    Problem:Implement regular expression matching with support for '.' and '*'. '.' Matches any single c ...

  8. LeetCode第[4]题(Java):Median of Two Sorted Arrays 标签:Array

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

  9. LeetCode第[29]题(Java):Divide Two Integers

    题目:两整数相除 难度:Medium 题目内容: Given two integers dividend and divisor, divide two integers without using ...

随机推荐

  1. 相似性分析之Jaccard相似系数

    Jaccard, 又称为Jaccard相似系数(Jaccard similarity coefficient)用于比较有限样本集之间的相似性与差异性.Jaccard系数值越大,样本相似度越高 公式: ...

  2. 第四课(2)——mysql配置参数讲解

    *****************general***************** user 启动mysql domain的用户 port 数据库端口号 socket 数据库socket文件的路径 p ...

  3. Java基础 - 面向对象 - 类方法传参

    调用方法时可以给该方法传递一个或多个值,传给方法的值叫实参,在方法内部,接收实参的变量叫做形参,形参的声明语法与变量的声明语法一样.形参只在方法内部有效. Java中方法的参数主要有3种,分别为值参数 ...

  4. 全面解析JavaScript中“&&”和“||”操作符(总结篇)

    1.||(逻辑或), 从字面上来说,只有前后都是false的时候才返回false,否则返回true. ? 1 2 3 4 alert(true||false); // true alert(false ...

  5. shell function/for in/for (())/string concat/has dir/rename using regex/if(())/exit/execute command and pass value to variable/execute python

    #!/bin/bash #remove the MER.*_ in file name for all the files in a dir function getdir(){ for elemen ...

  6. 使用数组初始化list

    ArrayList<String> names = new ArrayList<String>(Arrays.asList("Delete","I ...

  7. Css选择器定位详解

    1.使用 class 属性来定位元素,方法如下: driver.findElement(By.cssSelector("input.login")); 即可以先指定一个 HTML的 ...

  8. 我的Android进阶之旅------>Java全角半角的转换方法

    一中文全角和半角输入的区别 1全角指一个字符占用两个标准字符位置 2半角指一字符占用一个标准的字符位置 3全角与半角各在什么情况下使用 4全角和半角的区别 5关于全角和半角 6全角与半角比较 二转半角 ...

  9. Django - 权限分配、权限组件与CRM整合

    一.权限分配 需求:为用户分配角色,为角色分配权限,如下图效果: 1.视图代码: from django.shortcuts import render from django.http import ...

  10. CSS:列表样式(设置列表项的标志图案/位置)

    通过CSS 列表属性能够放置.改变列表项标志.或者将图像作为列表项标志. 代码整理自w3school:http://www.w3school.com.cn 效果图: watermark/2/text/ ...