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的方法,需要想到特殊样例。例如
Input:
s = "”
p = "**"
Output: true
就是有连续多个*
在开头,需要做个预处理操作,否则过不了。
dp数组构造
dp[i][j]
代表p从[1…i],s从[1…j],这两个字符串是否匹配(字符串下标从1开始)
dp[0][0] 代表两个空字符串,显然是匹配的。
dp[0][i] 代表p串为空
dp[i][0] 代表s串为空
if s[j] == p[i] || p[i] == '?'
dp[i][j] = dp[i-1][j-1] // 去掉s,p末端
else if p[i] == '*'
dp[i][j] = 1 if dp[i-1][k] == 1 (0 <= k <= j) // 去掉p末端
代码
class Solution {
bool dp[2000][2000]={0};
public:
bool isMatch(string s1, string s2) {
int n=s1.size(), m=s2.size();
for(int j=0;s2[j]=='*' && j<m;j++) // 开头预处理,重要
for(int i=0;i<=n;i++)
dp[j+1][i]=true;
dp[0][0] = true;
for(int i=0;i<m;i++)
for(int j=0;j<n;j++)
if(s2[i]=='*')
for(int k=0;!dp[i+1][j+1]&&k<=j+1;k++)
dp[i+1][j+1]=dp[i][k];
else if(s2[i]=='?'||s1[j]==s2[i])
dp[i+1][j+1]=dp[i][j];
return dp[m][n];
}
};