剑指offer Java版 面试题19. 正则表达式匹配

题目描述

请实现一个函数用来匹配包括’.‘和’‘的正则表达式。模式中的字符’.‘表示任意一个字符,而’'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配。

测试用例

  • 功能测试(模式字符串里包含普通字符、‘.’、‘’;模式字符串和输入字符串匹配/不匹配;“.”这个组合真的是吃屎)
  • 特殊输入测试(输入字符串和模式字符是null、空字符串)

题目考点

  • 考察应聘者对字符串的编程能力
  • 考察应聘者对正则表达式的理解
  • 考察应聘者思维的全面性。在应聘者写完代码之后,面试官会要求他测试自己的代码,这个时候应聘者要充分考虑普通字符、‘.’、‘*’三者的排列组合,尽量完备地想出所有可能的测试用例。

image-20201219210046613

因此,本题的状态共有 m × n m \times n m×n 种,应定义状态矩阵 dp , d p [ i ] [ j ] dp[i][j] dp[i][j]代表 s [ : i ] s[:i] s[:i] p [ : j ] p[:j] p[:j]是否可以匹配。

做好状态定义,接下来就是根据 「普通字符」 , 「.」 , 「*」三种字符的功能定义,分析出动态规划的转移方程。

image-20201219210257880

复杂度分析:

  • 时间复杂度 O ( M N ) O(MN) O(MN) : 其中 M, NM,N 分别为 s 和 p 的长度,状态转移需遍历整个 dp 矩阵;
  • 空间复杂度 O ( M N ) O(MN) O(MN) : 状态矩阵 dp 使用 O ( M N ) O(MN) O(MN) 的额外空间。

代码

class Solution {
    public boolean isMatch(String s, String p) {
        int m = s.length() + 1, n = p.length() + 1;
        boolean[][] dp = new boolean[m][n];
        dp[0][0] = true;
        for(int j = 2; j < n; j += 2)
            dp[0][j] = dp[0][j - 2] && p.charAt(j - 1) == '*';
        for(int i = 1; i < m; i++) {
            for(int j = 1; j < n; j++) {
                dp[i][j] = p.charAt(j - 1) == '*' ?
                    dp[i][j - 2] || dp[i][j - 1] || dp[i - 1][j] && (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.') :
                    dp[i - 1][j - 1] && (p.charAt(j - 1) == '.' || s.charAt(i - 1) == p.charAt(j - 1))
            }
        }
        return dp[m - 1][n - 1];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值