LeetCode 044 Wildcard Matching
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 <font face="monospace">?</font>
or ``.Example 1:
Input:
s = “aa”
p = “a”
Output: false
Explanation: “a” does not match the entire string “aa”.
Example 2:
Input:
s = “aa”
p = ““
Output: true
Explanation: ‘‘ matches any sequence.
Example 3:
Input:
s = “cb”
p = “?a”
Output: false
Explanation: ‘?’ matches ‘c’, but the second letter is ‘a’, which does not match ‘b’.
Example 4:
Input:
s = “adceb”
p = “ab”
Output: true
Explanation: The first ‘‘ matches the empty sequence, while the second ‘‘ matches the substring “dce”.
Example 5:
Input:
s = “acdcb”
p = “ac?b”
*Output: false
题目大意:
通配符外卡匹配问题,有特殊字符”*“和”?”,其中”?” 能代替任何字符,”*“能代替任何字符串。
解题思路:
这是经典题。两字符串匹配题基本就是DP而且知道子问题答案可以推导下一个。
- 定义dp[i][j]为字符串s[i-1]和p[j-1]是否能匹配。
- 递归式为
1
2dp[i][j] = dp[i-1][j-1] && (p[j-1] == ? || s[i-1] == p[j-1]) if p[j-1] != \*
dp[i-1][j] || dp[i][j-1] if p[j-1] == \*
第一种情况为非*,通配一样字符或?
第二种情况为*,如果通配就是只移动s,dp[i-1][j]。若不通配(通配完)就只移动p。
- 方向为从左到右,从上到下。初始值为dp[0][0] = true。以及若s为空,p为多个*时候,dp[0][j]=true。
注意事项:
- 递归式含*不匹配情况dp[i][j-1],容易忽略。
- 初始化s为空,p为多个*。根据递归式来写,i=0时,递归式只剩下dp[i][j-1]。将i = 0带入到内外循环代码实现即可(先写内外循环)
- 模板问题: dp初始化先col再row; i循环到len(dp)而不是len(s); 用到p时候是p[i - 1]而不是p[i]
Python代码:
1 | def isMatch(self, s: str, p: str) -> bool: |
注意事项:
- 递归式含*不匹配情况dp[i][j-1],我写的时候忽略了。
- 初始化s为空,p为多个*。此情况其实与递归式符合,因为i=1开始,所以i=0的时候,dp[i-1][j]为负值省去,
只取dp[i][j-1]。 - 一开始写的corner case并入到递归式处理。
Java代码:
1 | public boolean isMatch(String s, String p) { |
算法分析:
时间复杂度为O(n*m)
,空间复杂度为O(n*m)
。