携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情
题目
给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。
'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。
两个字符串完全匹配才算匹配成功。
说明:
- s 可能为空,且只包含从 a-z 的小写字母。
- p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。
示例 1
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
示例 2
输入:
s = "aa"
p = "*"
输出: true
解释: '*' 可以匹配任意字符串。
示例 4
输入:
s = "adceb"
p = "*a*b"
输出: true
解释: 第一个 '*' 可以匹配空字符串, 第二个 '*' 可以匹配字符串 "dce".
示例 5
输入:
s = "acdcb"
p = "a*c?b"
输出: false
题解
思路
本题难点在于处理星号的匹配,用 iStar 和 jStar 表示星号在 s 和 p 中匹配的位置,初始值为-1,i 和 j 表示当前匹配的位置,匹配过程如下:
- 如果 s 和 p 中字符匹配,则分别自增 i 和 j
- 否则如果 p 中当前字符为星号,则标记 iStar 和 jStar,同时自增 j
- 否则如果 iStar >= 0,表示之前匹配过星号,因为星号可以匹配任意字符串,所以继续递增 i,同时移动 j 为 jStar 下一个字符
- 否则返回 false
当 s 中字符匹配完,p 中字符不能有除星号以外字符
代码
class Solution {
public:
bool isMatch(string s, string p) {
int i = 0, j = 0, iStar = -1, jStar = -1, m = s.size(), n = p.size();
while (i < m) {
if (j < n && (s[i] == p[j] || p[j] == '?')) {
++i, ++j;
} else if (j < n && p[j] == '*') {
iStar = i;
jStar = j++;
} else if (iStar >= 0) {
i = ++iStar;
j = jStar + 1;
} else return false;
}
while (j < n && p[j] == '*') ++j;
return j == n;
}
};
结语
业精于勤,荒于嬉;行成于思,毁于随。