10. Regular Expression Matching And 44. Wildcard Matching

PS:leetcode第10题和第44题是动态规划的类型的题,十分类似,可以放一起,当然第10题会难一些。

一、第10题 - 暴力递归

public static boolean isMatch(String str, String pattern) {
        return process(str.toCharArray(), pattern.toCharArray(), 0, 0);
    }

    //给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
    // '.' 匹配任意单个字符
    // '*' 匹配零个或多个前面的那一个元素
    // 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
    public static boolean process(char[] str, char[] pattern, int si, int pi){
        if (si == str.length && pi == pattern.length){
            return true;
        }

        //pi没有来到终点位置
        if (si == str.length){
            return (pi + 1 < pattern.length && pattern[pi + 1] == '*') && process(str, pattern, si, pi + 2);
        }

        //si没有来到终点位置
        if (pi == pattern.length){
            return false;
        }

        //pi + 1 不是 *
        if (pi + 1 >= pattern.length || pattern[pi + 1] != '*'){
            return (str[si] == pattern[pi] || pattern[pi] == '.') && process(str, pattern, si + 1, pi + 1);
        }

        //pi + 1 是 *
        //不管是 不相等 ?*变成0 还是相等?*变成0 都是这个逻辑
        if (process(str, pattern, si, pi + 2)){
            return true;
        }

        while (si < str.length && (str[si] == pattern[pi] || pattern[pi] == '.')){
            //变成1个  si+1 pi+2 后面的自己去玩
            //变成2个  si+2 pi+2 后面的自己去玩
            if (process(str, pattern, si + 1, pi + 2)){
                return true;
            }
            si++;
        }
        return false;
    }

二、第10题 - 暴力递归 + 斜率优化

public static boolean isMatch(String str, String pattern) {
        return process(str.toCharArray(), pattern.toCharArray(), 0, 0);
    }

    //给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。
    // '.' 匹配任意单个字符
    // '*' 匹配零个或多个前面的那一个元素
    // 所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
    public static boolean process(char[] str, char[] pattern, int si, int pi){
        if (si == str.length && pi == pattern.length){
            return true;
        }

        //pi没有来到终点位置
        if (si == str.length){
            return (pi + 1 < pattern.length && pattern[pi + 1] == '*') && process(str, pattern, si, pi + 2);
        }

        //si没有来到终点位置
        if (pi == pattern.length){
            return false;
        }

        //pi + 1 不是 *
        if (pi + 1 >= pattern.length || pattern[pi + 1] != '*'){
            return (str[si] == pattern[pi] || pattern[pi] == '.') && process(str, pattern, si + 1, pi + 1);
        }

        //pi + 1 是 *
        //si = 3 pi = 7
        //si [3 4 5 6]
        //pi [9 9 9 9]

        //si = 2 pi = 7
        //si 2 [3 4 5 6]
        //pi 9 [9 9 9 9]
        //si = 2 pi = 7 -> si = 3 pi = 7  + si = 2 pi = 9
        //斜率优化
        if ((str[si] == pattern[pi] || pattern[pi] == '.') && process(str, pattern, si + 1, pi)){
            return true;
        }

        return process(str, pattern, si, pi + 2);
    }

三、第10题 - 动态规划

public static boolean isMatch1(String s, String p) {
        int n = s.length();
        int m = p.length();

        char[] str = s.toCharArray();
        char[] pattern = p.toCharArray();

        //0 ... n
        //0 ... m
        boolean[][] dp = new boolean[n + 1][m + 1];
        dp[n][m] = true;

        //填写最后一行
        for (int pi = m - 1; pi >= 0; pi--) {
            dp[n][pi] = (pi + 1 < pattern.length && pattern[pi + 1] == '*') && dp[n][pi + 2];
        }

        //最后一列不用填写 因为pi来到结束位置  但si没有来到结束位置 默认是false

        //为什么要单独判断第二列 因为一个普遍位置依赖pi + 2列
        //填写倒数第二列
        //pattern只剩下一个字符 但0 ... n - 2 大于一个字符,那么这些位置不用填写 默认false
        //但是需要判断[n - 1][m - 1]这个位置 如果相等或者pattern的这个位置"." 那么就是true 否则false
        if (n > 0 && m > 0){
            dp[n - 1][m - 1] = (str[n - 1] == pattern[m - 1] || pattern[m - 1] == '.');
        }

        for (int si = n - 1; si >= 0; si--) {
            for (int pi = m - 2; pi >= 0; pi--) {
                if (pi + 1 >= pattern.length || pattern[pi + 1] != '*'){
                    dp[si][pi] = (str[si] == pattern[pi] || pattern[pi] == '.') && dp[si + 1][pi + 1];
                }else{
                    if ((str[si] == pattern[pi] || pattern[pi] == '.') && dp[si + 1][pi]){
                        dp[si][pi] = true;
                    }else{
                        dp[si][pi] = dp[si][pi + 2];
                    }
                }
            }
        }
        return dp[0][0];
    }

四、第44题 - 暴力递归(会超时 哈哈哈

//给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。
    // '?' 可以匹配任何单个字符。
    //'*' 可以匹配任意字符串(包括空字符串)。
    public static boolean isMatch10(String s, String p) {
        return process10(s.toCharArray(), p.toCharArray(), 0, 0);
    }

    public static boolean process10(char[] str, char[] pattern, int si, int pi){
        if (si == str.length && pi == pattern.length){
            return true;
        }

        if (si == str.length){
            return pattern[pi] == '*' && process10(str, pattern, si, pi + 1);
        }

        if (pi == pattern.length){
            return false;
        }

        if (pattern[pi] != '*'){
            return (str[si] == pattern[pi] || pattern[pi] == '?') && process10(str, pattern, si + 1, pi + 1);
        }

        //si 4 5 6 7 8 (9) 9 - 4 = 5个数
        //pi *
        for (int len = 0; len <= str.length - si; len++) {
            if (process10(str, pattern, si + len, pi + 1)){
                return true;
            }
        }

        return false;
    }

五、第44题 - 暴力递归 + 斜率优化(依然会超时 哈哈哈

//给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。
    // '?' 可以匹配任何单个字符。
    //'*' 可以匹配任意字符串(包括空字符串)。
    public static boolean isMatch10(String s, String p) {
        return process10(s.toCharArray(), p.toCharArray(), 0, 0);
    }

    public static boolean process10(char[] str, char[] pattern, int si, int pi){
        if (si == str.length && pi == pattern.length){
            return true;
        }

        if (si == str.length){
            return pattern[pi] == '*' && process10(str, pattern, si, pi + 1);
        }

        if (pi == pattern.length){
            return false;
        }

        if (pattern[pi] != '*'){
            return (str[si] == pattern[pi] || pattern[pi] == '?') && process10(str, pattern, si + 1, pi + 1);
        }

        //斜率优化
        if (process10(str, pattern, si + 1, pi)){
            return true;
        }

        if (process10(str, pattern, si, pi + 1)){
            return true;
        }

        return false;
    }

六、第44题 - 动态规划

public static boolean isMatch11(String s, String p) {
        int n = s.length();
        int m = p.length();
        char[] str = s.toCharArray();
        char[] pattern = p.toCharArray();
        boolean[][] dp = new boolean[n + 1][m + 1];
        dp[n][m] = true;

        for (int pi = m - 1; pi >= 0; pi--) {
            dp[n][pi] = pattern[pi] == '*' && dp[n][pi + 1];
        }

        for (int si = n - 1; si >= 0; si--) {
            for (int pi = m - 1; pi >= 0; pi--) {
                if (pattern[pi] != '*'){
                    dp[si][pi] = (str[si] == pattern[pi] || pattern[pi] == '?') && dp[si + 1][pi + 1];
                }else{
                    dp[si][pi] = dp[si + 1][pi] || dp[si][pi + 1];
                }
            }
        }

        return dp[0][0];
    }

猜你喜欢

转载自blog.csdn.net/axin1240101543/article/details/120509214