leetcode--10.正则表达式匹配

题目:

给定一个字符串s,以及一个匹配字符串p,要求判断s是否符合p的规则。

增加条件:

s以及p可以是26个英文小写字母,p中可以存在 '.' 以及 '*'

'.' : 这个符号可以代表任意字母

'*' : 这个符号需要和其p中上一个符号sign组合,即sign*,表示有 0或者1或者2或者……个sign。

思路:

这题是典型的动态规划,主要工作需要创建其状态转移公式。

假设s的长度为sLen,p的长度为pLen,需要创建一个布尔类型的二维数组存储状态,

即dp[sLen][pLen]。假设当前识别到s的第i位符号,p的第j位符号,即需要确定dp[i][j]的状态。可以分成两种情况:

1. p[j-1] != '*'

这个状态是最简单的,只需要去考虑是否s[i-1] == p[j-1] 或者p[j] == '.',如果相等则dp[i][j] = dp[i-1][j-1],否则就是false。

2. p[j-1] == '*'

这个状态又可以分为2种情况:

2.1 s[i-1] == p[j-2](即当前s的符号可以与p中'*'前一个符号相匹配)

这个时候使dp[i][j] = dp[i-1][j],即看s中的第 i-1 位置上的符号是否与p中 j 以及 j-1 位置上的 '*'组合 匹配。或者dp[i][j] = dp[i][j-2],即之前已将s[0:i-1]与p[0:j-3]匹配成功,那可以将这次的 '*'组合 直接省略不看('*'组合 看成0个当前符号)。

2.2 s[i-1] != p[j-2](即当前s的符号不可以与p中'*'前一个符号相匹配)

这个时候需要将 '*'组合 直接省去,去考虑dp[i][j] = dp[i][j-2]

代码:

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

这道题有点难度,欢迎大家提供更有效的解决方案

你可能感兴趣的:(leetcode,算法,职场和发展)