LeetCode.044.Wildcard Matching 通配符匹配
题目描述
44 Wildcard Matching
https://leetcode-cn.com/problems/wildcard-matching/
给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 ‘?’ 和 ‘*’ 的通配符匹配。
‘?’ 可以匹配任何单个字符。
‘*’ 可以匹配任意字符串(包括空字符串)。
两个字符串完全匹配才算匹配成功。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。
示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:
s = "aa"
p = "*"
输出: true
解释: '*' 可以匹配任意字符串。
示例 3:
输入:
s = "cb"
p = "?a"
输出: false
解释: '?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。
示例 4:
输入:
s = "adceb"
p = "*a*b"
输出: true
解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".
示例 5:
输入:
s = "acdcb"
p = "a*c?b"
输出: false
相似题目
LeetCode.010.Regular Expression Matching 正则表达式匹配
LeetCode.044.Wildcard Matching 通配符匹配
解题过程
dp[i][j]
表示 s 前 i 个字符和 p 前 j 个字符是否匹配,即 s[0...i-1]
和 p[0...j-1]
是否匹配
则 dp[0][0] = true
即空串和空串是匹配的,dp[s.length][p.length]
就是最终结果
1、当 p 的第 j 个字符 p[j-1]
不是 *
时,如果 p[j-1]
是 ?
(百搭) 或者和 s[i-1]
相等,则 dp[i][j] = dp[i-1][j-1]
2、当 p 的第 j 个字符 p[j-1]
是 *
时,可以匹配 0 个或多个任意字符:
(1) 匹配 0 个字符时,即忽略星号,dp[i][j] = dp[i][j-1]
(2) 匹配任意字符时,不用管 s[i-1]
是什么,dp[i][j] = dp[i-1][j]
初始条件:
1、dp[0][0] = true
,即 s,p 都是空串时可以匹配
2、p 为空 s 不为空时是无法匹配,java 中 boolean 数组默认值就是 false,无需初始化
3、s 为空 p 不为空时,只有当 p 全是 * 号时才能匹配
时间复杂度 O(mn)
,空间复杂度 O(mn)
private static class SolutionV202007 {
public boolean isMatch(String s, String p) {
// dp[i][j] 表示 s 前 i 个字符组成的子串和 p 前 j 个字符组成的子串是否匹配
boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
dp[0][0] = true; // s,p 都是空串时可以匹配
// p 为空 s 不为空时是无法匹配,boolean 数组默认值就是 false,无需初始化
// s 为空 p 不为空时,只有当 p 全是 * 号时才能匹配
for (int i = 1; i <= p.length(); i++) {
if (p.charAt(i - 1) == '*') {
dp[0][i] = true;
} else {
break;
}
}
// 遍历填表,i,j 遍历的是二维表格 dp 的下标
for (int i = 1; i <= s.length(); i++) {
for (int j = 1; j <= p.length(); j++) {
if (p.charAt(j - 1) != '*') {
// p[j-1] 不是星号时, p[j-1]==s[i-1] 或 p[j-1]=='?' 时, dp[i][j] = dp[i-1][j-1]
dp[i][j] = dp[i - 1][j - 1] && (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?');
} else {
// p[j-1] 是星号,可以匹配 0 个或多个任意字符
// 匹配 0 个字符时,dp[i][j] = dp[i][j-1],匹配任意字符时,dp[i][j] = dp[i-1][j]
dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
}
}
}
return dp[s.length()][p.length()];
}
}
GitHub代码
algorithms/leetcode/leetcode/_044_WildcardMatching.java
https://github.com/masikkk/algorithms/blob/master/leetcode/leetcode/_044_WildcardMatching.java
页面信息
location:
protocol
: host
: hostname
: origin
: pathname
: href
: document:
referrer
: navigator:
platform
: userAgent
: