代码重构:leetcode 10. 正则表达式匹配

142 阅读1分钟

10. 正则表达式匹配

首先定义:

  • 设s为原串,p为匹配符串

  • dp[i] [j] 代表,s串的1到i个字符是否与p串的1到j个字符匹配

于是我们在回到定义:

若 s[i] == p[j] || p[j]=='.' ,那么显然dp[i+1] [j+1] =dp[i] [j];

如果p[j]=='*',那么我们考虑以下三种情况

  1. 此时匹配*表示空,则dp[i+1] [j+1] = dp[i+1] [j-1]
  2. 此时匹配*表示1,则dp[i+1] [j+1] = dp[i+1] [j]
  3. 此时匹配*表示多个,则必须满足先匹配一个的情况即: s[i] == p[j-1] || p[j-1]=='.'
    • 此时,dp[i+1] [j+1] = dp[i] [j+1]

但此时还需要考虑初始条件:

显然按照定义dp[0] [0] =true

因为dp[1~k] [0]不可能为真,不必再次初始化

而dp[0] [1~k]是可能为真的,于是需要初始化,如果p[j]=='*' 那么dp[0] [j+1] =dp[0] [j-1]

代码如下:

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