44. 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 lettersa-z
.p
could be empty and contains only lowercase lettersa-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
DP的方法要先建立一個size為(m + 1) * (n + 1)的2D dp table,dp[i][j]代表s[0...i - 1]和p[0...j-1]是否match。 dp[0][j] = dp[0][j - 1] if j > 1 and p[j - 1] == '*' 1. dp[i][j] = dp[i - 1][j - 1] if s[i - 1] == p[j - 1] || p[j - 1] == '?' 2. dp[i][j] = dp[i - 1][j] || dp[i][j - 1] if p[j - 1] == '*' dp[i - 1][j]的情形是s[0...i - 2]和p[0...j - 1]match然後p[j - 1]這個'*'要match更多的characters。 dp[i][j - 1]的情形是s[0...i - 1]和p[0...j - 2]match然後p[j - 1]這個'*'要match empty sequence。
// Dynamic programming
bool isMatch(string s, string p) { // time: O(m * n); space: O(m * n)
int m = s.length(), n = p.length();
vector<vector<bool> > dp(m + 1, vector<bool>(n + 1, false));
dp[0][0] = true;
for (int j = 1; j <= n; ++j) {
dp[0][j] = dp[0][j - 1] && p[j - 1] == '*';
}
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (p[j - 1] == '*') {
dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
// dp[i][j - 1]: * represents empty sequence since s[0...i) matches p[0...j-1)
// dp[i - 1][j]: * represents one more characters since s[0...i-1) matches p[0...j)
} else {
dp[i][j] = dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '?');
}
}
}
return dp.back().back();
}
// Space Optimized Dynamic Programming
bool isMatch(string s, string p) { // time: O(m * n); space: O(n)
int m = s.length(), n = p.length();
vector<bool> dp(n + 1, false);
dp[0] = true;
for (int j = 1; j <= n; ++j) {
dp[j] = dp[j - 1] && p[j - 1] == '*';
}
for (int i = 1; i <= m; ++i) {
int upper_left = dp[0];
dp[0] = false;
for (int j = 1; j <= n; ++j) {
int upper = dp[j];
if (p[j - 1] == '*')
dp[j] = dp[j - 1] || upper;
else
dp[j] = upper_left && (s[i - 1] == p[j - 1] || p[j - 1] == '?');
upper_left = upper;
}
}
return dp.back();
}
// Greedy
bool isMatch(string s, string p) { // time: O(m or n); space: O(1)
int m = s.length(), n = p.length();
int i = 0, j = 0, match = -1, asterisk = -1;
while (i < m) {
if (j < n && (p[j] == s[i] || p[j] == '?')) {
++i;
++j;
} else if (j < n && p[j] == '*') { // find *, move j forward
match = i;
asterisk = j++;
} else if (asterisk >= 0) { // last pattern is *, move i forward
i = ++match;
j = asterisk + 1;
} else return false;
}
while (j < n && p[j] == '*') ++j;
return j == n;
}
Last updated
Was this helpful?