leetcode Java二刷:10. 正则表达式匹配

题目10. 正则表达式匹配

思路:动态规划

  • s[i] == p[j],或者p[j] == '.',那么s[i]p[j]匹配,转移方程:dp[i][j] = dp[i - 1][j - 1]
  • s[i] != p[j],并且p[j] == '*',此时,p往前看一位:
    • s[i] != p[j-1],表示s[i]无法与*前的字母匹配,因此dp[i][j] = dp[i][j - 2]
    • s[i] == p[j-1],此时分3种情况:
      (1) s[i]p[j-1]匹配,dp[i][j] = dp[i][j - 1]
      (2) s[i-1]p[j]可以匹配,那么再来一个*前的字母s[i]也可以匹配成功,dp[i][j] = dp[i - 1][j]
      (3) *表示0个,s[i]直接和p[j-2]匹配,dp[i][j] = dp[i][j - 2]。三种情况取或即可。
  • s[i]p[j]都是字母且不相等,无法匹配,dp[i][j] = false

初始化:

  • dp[0][0] = true
  • p[j] == '*'j== 0j==1dp[0][j] = true
  • p[j] == '*'j > 2dp[0][j] = dp[0][j-2]
  • 其余情况 dp[0][j] = false

代码:

class Solution {
    public boolean isMatch(String s, String p) {
        int lens = s.length();
        int lenp = p.length();
        boolean[][] dp = new boolean[lens + 1][lenp + 1];
        // init
        dp[0][0] = true;
        for (int j = 1; j <= lenp; j++) {
            if (p.charAt(j-1) == '*') {
                if (j-2 > 0) {
                    dp[0][j] = dp[0][j-2];
                }
                else {
                    dp[0][j] = true;
                }
            }
            else {
                dp[0][j] = false;
            }
        }

        for (int i = 1; i <= lens; i++) {
            for (int j = 1; j <= lenp; 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 (j - 2 >= 0 && (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.')) {
                            dp[i][j] = dp[i][j - 1] || dp[i - 1][j] || dp[i][j - 2];
                        }
                        else if (j - 2 >= 0 && s.charAt(i - 1) != p.charAt(j - 2)) {
                            dp[i][j] = dp[i][j - 2];
                        }

                    }
                    else {
                        dp[i][j] = false;
                    }
                }

            }
        }

       return dp[lens][lenp];

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值