剑指 Offer 19 正则表达式匹配

 

 

解题思路分析

动态规划的思想,状态转移方程:长度为m与n的字符串进行匹配,可以转换为长度为m-1与n-1的字符串进行匹配的结果&最后两个字符进行匹配的结果

图片引用自biliblili up主 香辣鸡排蛋包饭

ac8052794e4d26f400feef067ef3fca

 

afa565bcf58e67cbf0fdcfabb491af2

 

 

18df65505b51c025e045fe10f5cbd39

此时根据正则字符串的最后一个元素来进行分类

  1. 若最后一个元素为字母或者 ' . ',则可以直接进行比较看是否相等,得到此时的状态

  2. 若最后一个元素为 ' * ' ,表示前面的字母重复了N次,而且N>=0;

  3. 此时再对N的取值进行分类,当N=0和N>0时,两者成立一个即可

    N=0时,将字符串的最后一位与正则字符串的倒数第三个元素进行匹配

    N>0时,将字符串最后一位与正则字符串重复的那个元素进行匹配

注意:动态规划的状态解释为 字符串的前 i 个元素与正则的前 j 个元素进行匹配的结果,dp [0] [0]表示两者均为空的情况

 

class Solution {
    public static void main(String[] args) {
        String s = "aa";
        String p = "a*";
        Solution solution = new Solution();
        solution.isMatch(s,p);
    }
    public boolean isMatch(String s, String p) {
        int m = s.length();
        int n = p.length();
        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;    ////这个条件需要放在前面,后面的初始化需要用到dp[0][0]=true 这个条件
        for (int i = 1; i <= m; ++i) {
            dp[i][0] = false;
        }
        for (int i = 2; i <= n; i += 2) {
            if (p.charAt(i - 1) == '*') {
                dp[0][i] = dp[0][i - 2];
            } else {
                dp[0][i] = false;
            }
        }
​
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (p.charAt(j - 1) == '*') {
                    if (dp[i][j - 2]) dp[i][j] = true;
                    else if (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.') {
                        dp[i][j] = dp[i - 1][j];
                    }
                } else {
                    if (p.charAt(j - 1) == '.') {
                        dp[i][j] = dp[i - 1][j - 1];
                    } else if (p.charAt(j - 1) == s.charAt(i - 1)) {
                        dp[i][j] = dp[i - 1][j - 1];
                    }
                }
            }
        }
        return dp[m][n];
    }
}

 

 

 

posted @ 2022-02-10 14:10  raindance1024  阅读(56)  评论(0)    收藏  举报