Wildcard Matching
update Sep 17 2018, 18:20
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 *
.
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 = "*a*b"
Output: true
Explanation: The first '*' matches the empty sequence, while the second '*' matches the substring "dce".
Example 5:
Input:
s = "acdcb"
p = "a*c?b"
Output: false
Basic Idea
利用dp的思路考虑,有如下规则:
dp[r][c] 表示从两string开始至 s[r] 和 p[c] 为止是否匹配。
Base case:
最左边一列为false,表示如果p中不使用任何字符则一个都无法匹配;
最上面一列看情况,表示s中不使用任何字符的匹配情况,如果p以*开头,对应位置为true,
则继续往右看,如果仍然是*,则继续设为true;
Rule:
if p[c-1]=='*': dp[r][c] = dp[r-1][c]||dp[r][c-1]
if p[c-1]=='?': dp[r][c] = dp[r-1][c-1]
if p[c-1]==其他: dp[r][c] = dp[r-1][c-1] && s[r-1]==p[c-1]
Java Code:
注意一个细节,如果p中除了*
的部分比s长,则不可能匹配,直接返回false;
class Solution {
public boolean isMatch(String s, String p) {
boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
for (int i = 0; i < dp.length; ++i) dp[i][0] = false;
for (int i = 0; i < dp[0].length; ++i) dp[0][i] = false;
dp[0][0] = true;
int len = 0; // p 除了*的长度
for (int i = 1; i < dp[0].length; ++i) {
if (p.charAt(i - 1) != '*') len++;
if (dp[0][i - 1] && p.charAt(i - 1) == '*') {
dp[0][i] = true;
}
}
if (len > s.length()) return false;
for (int r = 1; r < dp.length; ++r) {
for (int c = 1; c < dp[0].length; ++c) {
char sChr = s.charAt(r - 1);
char pChr = p.charAt(c - 1);
if (pChr == '*') {
dp[r][c] = dp[r - 1][c] || dp[r][c -1];
} else if (pChr == '?') {
dp[r][c] = dp[r - 1][c - 1];
} else {
dp[r][c] = dp[r - 1][c -1] && sChr == pChr;
}
}
}
return dp[dp.length - 1][dp[0].length - 1];
}
}