【LeetCode】44.通配符匹配

101 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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;
    }
};

结语

业精于勤,荒于嬉;行成于思,毁于随。