zoukankan      html  css  js  c++  java
  • Java算法练习——正则表达式匹配

    题目链接

    题目描述

    给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.' 和 '*' 的正则表达式匹配。

    '.' 匹配任意单个字符
    '*' 匹配零个或多个前面的那一个元素
    

    所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

    说明:

    • s 可能为空,且只包含从 a-z 的小写字母。
    • p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。

    示例 1

    输入:
    s = "aa"
    p = "a"
    输出: false
    解释: "a" 无法匹配 "aa" 整个字符串。
    

    示例 2

    输入:
    s = "aa"
    p = "a*"
    输出: true
    解释: 因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。
    

    示例 3

    输入:
    s = "ab"
    p = ".*"
    输出: true
    解释: ".*" 表示可匹配零个或多个('*')任意字符('.')。
    

    示例 4

    输入:
    s = "aab"
    p = "c*a*b"
    输出: true
    解释: 因为 '*' 表示零个或多个,这里 'c' 为 0 个, 'a' 被重复一次。因此可以匹配字符串 "aab"。
    

    示例 5

    输入:
    s = "mississippi"
    p = "mis*is*p*."
    输出: false
    

    题解 (回溯)

    public boolean isMatch(String text, String pattern) {
        if (pattern.isEmpty()) return text.isEmpty();
        boolean first_match = (!text.isEmpty() &&
                               (pattern.charAt(0) == text.charAt(0) || pattern.charAt(0) == '.'));
    
        if (pattern.length() >= 2 && pattern.charAt(1) == '*'){
            return (isMatch(text, pattern.substring(2)) ||
                    (first_match && isMatch(text.substring(1), pattern)));
        } else {
            return first_match && isMatch(text.substring(1), pattern.substring(1));
        }
    }
    

    题解 (动态规划)

    public boolean isMatch(String text, String pattern) {
        boolean[][] dp = new boolean[text.length() + 1][pattern.length() + 1];
        dp[text.length()][pattern.length()] = true;
    
        for (int i = text.length(); i >= 0; i--){
            for (int j = pattern.length() - 1; j >= 0; j--){
                boolean first_match = (i < text.length() &&
                                       (pattern.charAt(j) == text.charAt(i) ||
                                        pattern.charAt(j) == '.'));
                if (j + 1 < pattern.length() && pattern.charAt(j+1) == '*'){
                    dp[i][j] = dp[i][j+2] || first_match && dp[i+1][j];
                } else {
                    dp[i][j] = first_match && dp[i+1][j+1];
                }
            }
        }
        return dp[0][0];
    }
    

    复杂度分析

    不是很懂,力扣题解有写,大家看那个吧。

    手记

    对我这个菜鸡来说,这题挺难。现在只看懂了官方题解,后面过段时间还要多练习下。

  • 相关阅读:
    【NYOJ】[57]6174问题
    【NYOJ】[56]阶乘因式分解(一)
    【NYOJ】[56]阶乘因式分解(一)
    【看书】for,(do-)while的循环体执行
    【看书】for,(do-)while的循环体执行
    【NYOJ】[41]三个数从小到大排序
    【NYOJ】[41]三个数从小到大排序
    EndNote X7大客户版破解版
    [TomTom]安卓汉化版v1.3,中国及海外地图懒人包
    [TomTom]安卓汉化版v1.3,中国及海外地图懒人包
  • 原文地址:https://www.cnblogs.com/mxwbq/p/10956779.html
Copyright © 2011-2022 走看看