18.正则表达式匹配

请实现一个函数用来匹配包括'.'和'*'的正则表达式。

模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(含0次)。

在本题中,匹配是指字符串的所有字符匹配整个模式。

例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但是与"aa.a"和"ab*a"均不匹配。

数据范围:

输入字符串长度 [0,300]。

样例:

输入:
s="aa"
p="a*"
输出:
true

代码:

class Solution {
    public boolean isMatch(String s, String p) {
        //m为字符串s的长度,n为字符串p的长度
        int m = s.length(), n = p.length();
        // dp[i][j] 表示s[i..m-1]和p[j..n-1]是否匹配
        boolean[][] dp = new boolean[m + 1][n + 1];
        
        // 空字符串匹配空模式
        dp[m][n] = true;
        
        // 从后往前处理
        // i从m开始表示处理s的子串是空字符串,因为模式p可能包含像a*这样的模式,它可以匹配空字符串
        for (int i = m; i >= 0; i--) {
            for (int j = n - 1; j >= 0; j--) {
                // 检查当前第一个字符是否匹配:
                // i不能超出字符串长度
                // 字符相等或者模式为'.'(可以匹配任意字符)
                boolean firstMatch = i < m && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.');
                
                // 处理'*'情况
                if (j + 1 < n && p.charAt(j + 1) == '*') {
                    // 两种情况满足任意一种即可:
                    // 匹配0次:跳过当前字符和'*'(即j+2)
                    // 匹配1次:当前字符匹配成功,然后继续用*匹配剩下的字符串(i+1) 
                    dp[i][j] = dp[i][j + 2] || (firstMatch && dp[i + 1][j]);
                } else {
                    // 普通字符匹配:当前字符匹配成功,且剩下的也匹配成功
                    dp[i][j] = firstMatch && dp[i + 1][j + 1];
                }
            }
        }
        
        //最终结果是整个字符串和整个模式串是否匹配
        return dp[0][0];
    }
}
posted @ 2025-05-14 13:09  回忆、少年  阅读(4)  评论(0)    收藏  举报