LeetCode - 10.Regular Expression Matching

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

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

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

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.

PS : 默认pattern是符合正则式规则的。

第一次看到这个题的时候一点思路都没。直接看解答了,学习了一下动态规划(Dynamic Programming)

class Solution {
    public boolean isMatch(String s, String p) {
        int sLen = s.length();
        int pLen = p.length();
        boolean[][] dp = new boolean[sLen + 1][pLen + 1];
        dp[0][0] = true;//当s为空以及p为空时,匹配。
        for (int i = 0;i <= sLen;i++){//当s为空时,p == ".*" 等可以匹配,故从长度0开始。
            for (int j = 1; j <= pLen; j++) {//当p为空s不为空时,一定不匹配,bool数组初始化时已赋值为false,故从长度1开始。 
                if (p.charAt(j - 1) == '*'){
                    dp[i][j] = dp[i][j-2] //匹配零次前个字符
                            || (i > 0
                                && dp[i-1][j]//匹配第n次时的前提是,至少匹配n-1次时已成功
                                && (p.charAt(j - 2) == '.' || s.charAt(i - 1) == p.charAt(j - 2))); //匹配一次前个字符
                }else {
                    dp[i][j] = i > 0 //字符串为空时一定不匹配
                            && dp[i - 1][j - 1] //多匹配一个字符的前提是前面的字符已匹配成功
                            && (p.charAt(j - 1) == '.' || s.charAt(i - 1) == p.charAt(j - 1));//如果Pattern值为'.'时匹配所有,或者两个字符相等
                }
            }
        }
        return dp[sLen][pLen];
    }
}

稍微优化了一下空间占用:

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

参考链接

Dynamic Programming - GeeksforGeeks

什么是动态规划?动态规划的意义是什么? - 知乎

漫画:什么是动态规划? - 知乎

你可能感兴趣的:(LeetCode - 10.Regular Expression Matching)