Leetcode JAVA刷刷站(10)正则表达式匹配

一、题目概述

二、思路方向

在Java中,实现一个支持'.'和'*'的正则表达式匹配器,可以通过递归或动态规划(DP)的方法来完成。这里,我将使用动态规划的方法来解决这个问题,因为它更容易理解和实现。

动态规划的思路是,我们可以创建一个二维的布尔数组dp,其中dp[i][j]表示字符串s的前i个字符和模式p的前j个字符是否匹配。初始化时,dp[0][0]true(空字符串和空模式匹配),而dp[0][j](对于所有j > 0)只有在p的前j个字符都是*时才为true,因为*可以匹配零个字符。

接下来,我们遍历dp数组,填充剩余的条目。对于每个(i, j),我们考虑以下情况:

  1. 如果p[j-1]不是*,那么dp[i][j]为真当且仅当s[i-1] == p[j-1]p[j-1] == '.'dp[i-1][j-1]为真。
  2. 如果p[j-1]*,那么有两种可能性:
    • 忽略*和前面的字符,即看dp[i][j-2]
    • 匹配零个或多个前面的字符,这取决于dp[i-1][j](如果s[i-1]匹配p[j-2],则可以通过添加s[i-1]到匹配中)为真。

三、代码实现

java 复制代码
public class Solution {  
    public boolean isMatch(String s, String p) {  
        int m = s.length();  
        int n = p.length();  
          
        // 创建一个二维布尔数组dp  
        boolean[][] dp = new boolean[m + 1][n + 1];  
        dp[0][0] = true; // 空字符串和空模式匹配  
  
        // 初始化dp[0][j],只有当p全是*时才匹配  
        for (int j = 1; j <= n; j++) {  
            if (p.charAt(j - 1) == '*') {  
                dp[0][j] = dp[0][j - 2];  
            }  
        }  
  
        // 填充dp数组  
        for (int i = 1; i <= m; i++) {  
            for (int j = 1; j <= n; j++) {  
                if (p.charAt(j - 1) != '*') {  
                    dp[i][j] = (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.') && dp[i - 1][j - 1];  
                } else {  
                    // 两种情况:匹配0次或多次前面的字符  
                    dp[i][j] = dp[i][j - 2]; // 忽略*和前面的字符  
                    if (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.') {  
                        dp[i][j] = dp[i][j] || dp[i - 1][j];  
                    }  
                }  
            }  
        }  
  
        return dp[m][n];  
    }  
  
    public static void main(String[] args) {  
        Solution solution = new Solution();  
        System.out.println(solution.isMatch("aa", "a"));    // false  
        System.out.println(solution.isMatch("aa", "a*"));   // true  
        System.out.println(solution.isMatch("ab", ".*"));   // true  
        System.out.println(solution.isMatch("aab", "c*a*b")); // true  
        System.out.println(solution.isMatch("mississippi", "mis*is*p*.")); // false  
    }  
}

执行结果:

四、小结

这个实现通过动态规划解决了正则表达式的匹配问题,时间复杂度为O(mn),空间复杂度也为O(mn),其中m和n分别是字符串s和模式p的长度。

结语

因为遇见你,我才知道我也能具有美丽的记忆。

所以,无论你怎样对待我,

我都会用心去宽恕你的恨

用心去铭记你的好

!!!

相关推荐
Data 3177 分钟前
Hadoop三大组件之YARN(一)
java·大数据·数据库·数据仓库·hadoop·yarn
Mephisto.java22 分钟前
【力扣 | SQL题 | 每日四题】力扣1440, 1378, 1421, 1393, 1407
算法·leetcode·职场和发展
java_heartLake34 分钟前
设计模式之命令模式
java·设计模式·命令模式
攻城狮7号2 小时前
【4.5】图搜索算法-BFS和DFS求岛屿的最大面积
c++·算法·深度优先·宽度优先·图搜索算法
攻城狮7号3 小时前
【4.6】图搜索算法-DFS和BFS解合并二叉树
c++·算法·深度优先·宽度优先·图搜索算法
胡耀超6 小时前
Java多线程在单体、微服务、服务网格与云原生架构中的理解与线程安全保障:总结与对比
java·云原生·架构
武子康6 小时前
大数据-152 Apache Druid 集群模式 配置启动【下篇】 超详细!
java·大数据·clickhouse·flink·apache
wypdao6 小时前
探索后量子安全:基于格加密技术的未来密码学展望
算法·安全·密码学·量子计算
鸡鸭扣6 小时前
数据结构与算法:栈和队列的python(deque)实现(附有leetcode题20、1047、150逆兰波表达式、347前k个高频元素题解)
数据结构·python·算法·leetcode·力扣··队列
费曼乐园6 小时前
Spring中引入 @PostConstruct 注解的原因
java·spring