【线性 dp】A010_LC_正则表达式匹配(分类讨论)

一、Problem

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。

‘.’ 匹配任意单个字符
‘*’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。

输入:
s = "aab"
p = "c*a*b"
输出: true
解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。

二、Solution

方法一:dp

  • 定义状态
    • f [ i ] [ j ] f[i][j] 表示 s 的前 i i 个字符能否被 p 的前 j j 个字符匹配
  • 思考初始化:
    • f [ 0 ] [ 0 ] = t r u e f[0][0] = true ,表示空串与空串可匹配
    • f [ 0 ] [ j ] = f [ 0 ] [ j 2 ]   & &   p [ i 1 ] = f[0][j] = f[0][j-2]\ \&\&\ p[i-1] = * 表示字符串 p 的前 j j 个字符只有当 p [ j 2 ] p[j-2] 为空串,且 s [ j 1 ] s[j-1] * 时才可以匹配。
  • 思考状态转移方程:注: i 1 & & j 1 (i \geqslant 1 \&\& j \geqslant 1)
    • 如果 s [ i ] = p [ j ]     p [ j ] = . s[i] = p[j]\ ||\ p[j] = . 则有 f [ i ] [ j ] = f [ i 1 ] [ j 1 ] f[i][j] = f[i-1][j-1] ,否则 —>
    • 如果 p [ j ] = p[j] = * ,此时的 * 号有两种作用:
      • 清空:有 f [ i ] [ j ] = f [ i ] [ j 2 ] f[i][j] = f[i][j-2] ,即将字符串 p 的第 j 1 j-1 个字符清走,比如 (ab, abc*),就将字母 c 清走
      • 补全:如果 f [ i 1 ] [ j ]   & &   ( s [ i 1 ] = p [ j 1 ]     p [ j 1 ] = . ) f[i-1][j]\ \&\&\ (s[i-1] = p[j-1]\ ||\ p[j-1] = .) 即 (abbb,ab*),或者 (abbb,ab* / a.*)
  • 思考输出 f [ n ] [ m ] f[n][m]

还是有点复杂的,如果没有正则表达式基础的同学可能会有点晕,可以放一放…

class Solution {
    public boolean isMatch(String S, String P) {
        char s[] = S.toCharArray(), p[] = P.toCharArray();
        int n = s.length, m = p.length;
        boolean f[][] = new boolean[n+1][m+1];
        f[0][0] = true;
        for (int j = 2; j <= m; j++) 
            f[0][j] = f[0][j-2] && p[j-1] == '*';

        for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            if (s[i-1] == p[j-1] || p[j-1] == '.') {
                f[i][j] = f[i-1][j-1];
            } else if (p[j-1] == '*') {
                f[i][j] = f[i][j-2] || f[i-1][j] && (s[i-1] == p[j-2] || p[j-2] == '.');
            }
        }
        
        return f[n][m];
    }
}

复杂度分析

  • 时间复杂度: O ( n × m ) O(n × m)
  • 空间复杂度: O ( n × m ) O(n × m)

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/106878122