Leetcode第十题 字符串匹配 Regular Expression Matching

239 阅读2分钟

题目描述:给定两个字符串s和p,判断两个字符串是否匹配,其中p支持'.'和'*'。对这两个特殊字符的说明如下。

'.' : 可以匹配任意单个字符。

'*' : 可以匹配0到多个'*'前面的字符。

解题思路:字符串匹配类型的题,首先要明确匹配规则,其次是要确认求出题目结果的前置条件。下面我们简单列举下字符串匹配的规则。

1.简单情况

'.' 匹配任意字符

image.png

'*'匹配0个或者多个前面的字符

image.png 2 复杂情况

image.png 解法:

class Solution {
    public boolean isMatch(String s, String p) {
        int m=s.length(),n=p.length();
        //一个二维数组,f[m][n]表示s的0-m子串和p的0-n子串是否匹配
        boolean[][] f=new boolean[m+1][n+1];
        //初始化头节点
        f[0][0]=true;
        //初始化第一行数据,对*进行特殊处理,主要是为了后续处理
        //可以匹配0到多个'*'前面的字符,这里处理*代表0个的情况
        for(int j=2;j<=n;j++){
            //如果p的当前字符为*,*当作匹配0个处理
            //那么p中*和*之前的字符可以忽略,所以判断下j-2位置是否匹配
            f[0][j]= p.charAt(j-1)=='*' && f[0][j-2];
        }
        //遍历循环匹配情况
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                if(p.charAt(j-1) != '*'){
                    //如果匹配字符不是*,直接判断两个字符串中字符的值是否对等
                    f[i][j]=f[i-1][j-1] && (s.charAt(i-1) == p.charAt(j-1) || p.charAt(j-1)=='.');
                }else{
                    //如果是*,有以下两种情况
                    //1,*匹配0个字符,表示p中j-1可以忽略,直接判断f[i][j-2]
                    //2,*匹配一个以上字符,那么直接判断s[i-1]和p[j-2]的关系 && f[i-1][j]
                    //其中s[i-1]和p[j-2]判断当前字符的关系
                    //因为*可能匹配多个,还可能和.搭配,还需要知道f[i-1][j]的状态
                    f[i][j]=f[i][j-2] || (s.charAt(i-1)==p.charAt(j-2) || p.charAt(j-2)=='.') && f[i-1][j];
                }
            }
        }
        //最终的f[m][n]就是匹配结果
        return f[m][n];
    }
}

运行结果: Runtime: 4 ms, faster than 72.17% of Java online submissions for Regular Expression Matching.

Memory Usage: 42.5 MB, less than 36.99% of Java online submissions for Regular Expression Matching.