Leetcode 10. 正则表达式匹配

本文探讨了正则表达式匹配算法的实现,从纯递归方法到使用数组记录中途搜索结果进行优化,最终采用自底向上的动态规划解决时间复杂度过高的问题。通过逐步改进,实现了高效、稳定的正则表达式匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文仅仅记录自身代码的一步步演变过程,需要详细解答请前往官网查看
一、 纯递归求解

class Solution {
public:
    bool Match(string &s,string &p,int start_s,int start_p){
        int size_s = s.size(),size_p = p.size(),i = start_s, j = start_p;
        if(j == size_p) return i == size_s;
        if(i < size_s  && (j == size_p - 1 || p[j + 1] != '*')){
            if(p[j] != '.')
                return s[i] == p[j] && Match(s,p,i + 1, j + 1);
            else{
                return Match(s,p,i + 1, j + 1); 
            }
        }
        //p串第二位为 '*'
        if(j + 1 < size_p && p[j + 1] == '*') {// p串第二位为 '*'
            bool notuse = Match(s,p,i,j + 2);
            bool use = i == size_s ? false : ( (p[j] == '.' || s[i] == p[j]) && Match(s,p,i + 1,j) );
            return notuse || use;
        }
        //s 串已空 且 p串为单次匹配
        return false;
    }
    bool isMatch(string s, string p) {
        int size_s = s.size(),size_p = p.size(),i = 0, j = 0;
        return Match(s,p,0,0);
    }
};

时间复杂度过高,考虑用一个数组记录搜索分支的结果,遇到相同分支直接返回

二、用数组记录中途搜索结果进行优化
自顶向下

class Solution {
public:
    bool Match(string &s,string &p,int start_s,int start_p,vector<vector<int>> &dp){
        int size_s = s.size(),size_p = p.size(),i = start_s, j = start_p;
        if(dp[i][j] != 0) return dp[i][j] > 0;
        if(j == size_p) {
            dp[i][j] = i == size_s ? 1 : -1;
            return dp[i][j] > 0;
        }
        if(i < size_s  && (j == size_p - 1 || p[j + 1] != '*')){
            dp[i][j] = (p[j] == '.' || s[i] == p[j]) && Match(s,p,i + 1, j + 1,dp) ? 1 : -1;
            return  dp[i][j] > 0; 
        }
        //p串第二位为 '*'
        if(j + 1 < size_p && p[j + 1] == '*') {// p串第二位为 '*'
            bool notuse = Match(s,p,i,j + 2,dp);
            bool use = i == size_s ? false : ( (p[j] == '.' || s[i] == p[j]) && Match(s,p,i + 1,j,dp) );
            dp[i][j] = notuse || use ? 1 : -1;
            return dp[i][j] > 0 ;
        }
        //s 串已空 且 p串为单次匹配
        dp[i][j] = -1;
        return false;
    }
    bool isMatch(string s, string p) {
        int size_s = s.size(),size_p = p.size(),i = 0, j = 0;
        vector<vector<int>> dp(size_s + 1,vector<int>(size_p + 1,0));// 0 表示未访问, 1 表示 匹配,-1 表示不匹配
        return Match(s,p,0,0,dp);
    }
};

三、动态规划(自底向上)

class Solution {
public:
    bool isMatch(string s, string p) {
        int size_s = s.size(),size_p = p.size();
        vector<vector<bool> > dp ( size_s + 1,vector<bool>(size_p + 1,false) );
        //自底向上
        dp[size_s][size_p] = true;
        for(int i = size_s; i >= 0; i--){
            for(int j = size_p - 1; j >= 0;j--){
                bool first_match = i < size_s && (p[j] == '.' || s[i] == p[j]); // 首字母匹配
                if(j + 1 < size_p && p[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];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值