10. 正则表达式匹配 Regular Expression Matching

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'where: 

  • '.' Matches any single character.​​​​
  • '*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

 

Input: s = "aa", p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".

 

方法一、递归

如果没有*,我们依次比较即可

如果存在*,由于题目要求,*是跟着某个字符后面,我们可以1 、忽略*和*前面的字符  2、s和 *前的字符相同,则匹配s剩下的字符和*前即可

 

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));
        }

    }

 

方法二:动态规划

我们可以定义一个二维的 DP 数组,其中 dp[i][j] 表示 s[0,i) 和 p[0,j) 是否 match。

1.  P[i][j] = P[i - 1][j - 1], if p[j - 1] != '*' && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
2.  P[i][j] = P[i][j - 2], if p[j - 1] == '*' and the pattern repeats for 0 times;
3.  P[i][j] = P[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.'), if p[j - 1] == '*' and the pattern repeats for at least 1 times.

自底向上

enum Result {
        TRUE, FALSE
    }
    Result[][] memo;
    public boolean isMatch(String text, String pattern){
        memo = new Result[text.length() + 1][pattern.length() + 1];
        return dp(0, 0, text, pattern);
    }

    public boolean dp(int i, int j, String text, String pattern){
        if(memo[i][j] != null){
            return memo[i][j] == Result.TRUE;
        }
        boolean ans;
        if( j == pattern.length()){
            ans = i == text.length();
        }else{
            boolean first_match = ( i < text.length() &&
                    (pattern.charAt(j) == text.charAt(i) ||
                            pattern.charAt(j) == '.'));
            if(j + 1 < pattern.length() && pattern.charAt(j+1) == '*'){
                ans = (dp(i, j + 2, text, pattern) || first_match &&dp(I + 1, j, text, pattern));
            }else{
                ans = first_match && dp(i + 1, j +1, text, pattern);
            }
        }
        memo[i][j] = ans ? Result.TRUE : Result.FALSE;
        return ans;
    }

或者自顶向下

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];
    }

 

参考链接:

https://leetcode.com/problems/regular-expression-matching

https://leetcode-cn.com/problems/regular-expression-matching

posted @ 2020-11-28 18:03  diameter  阅读(105)  评论(0编辑  收藏  举报