10. 正则表达式匹配

10. 正则表达式匹配

给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.''*' 的正则表达式匹配。

  • '.' 匹配任意单个字符
  • '*' 匹配零个或多个前面的那一个元素

所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。

示例 1:

输入:s = "aa", p = "a"
输出:false
解释:"a" 无法匹配 "aa" 整个字符串。

示例 2:

输入:s = "aa", p = "a*"
输出:true
解释:因为 '*' 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 'a'。因此,字符串 "aa" 可被视为 'a' 重复了一次。

示例 3:

输入:s = "ab", p = ".*"
输出:true
解释:".*" 表示可匹配零个或多个('*')任意字符('.')。

提示:

  • 1 <= s.length <= 20
  • 1 <= p.length <= 30
  • s 只包含从 a-z 的小写字母。
  • p 只包含从 a-z 的小写字母,以及字符 .*
  • 保证每次出现字符 * 时,前面都匹配到有效的字符

思路:

​ 正则表达式匹配,经典的动态规划问题,在《剑指offer》中已经写过一次,这次再次遇到依然需要去看之前写过的题解,难免令人尴尬。还需要多加复习。

class Solution {
public:
    //备忘录
    map<string,bool>memo;
    bool isMatch(string s, string p) {
        //正则表达式经典动态规划问题
        return dp(s,0,p,0);
    }
    //dp表示s[0...]和p[0...]是否能够匹配
    bool dp(string s,int i,string p,int j){
        //base case
        if(j==p.size()){//如果p走完了,那么只要s也走完那么就匹配(注意:s走完了,p不一定走完)
            if(i==s.size())return true;
        }
        if(i==s.size()){//s已经走完,但是p没有走完
            //那么p要怎样才能走完呢?
            //'x*'这样成对
            if((p.size()-j)%2==1)return false;//如果剩下的元素数量不是偶数,就一定不符合规则
            //如果是偶数就去看是不是'x*'形式
            for(;j<p.size();j+=2){
                if(p[j+1]!='*')return false;
            }
            return true;
        }
        //每次判断前看备忘录
        string key=to_string(i)+','+to_string(j);
        if(memo.count(key))return memo[key];
        bool res=true;
        //从i和j位置开始判断
        //如果成功判断
        if(s[i]==p[j]||p[j]=='.'){
            //如果成功则还要去判断p的下一位是不是*,可以匹配0或n次
            //如果匹配0次则直接跳过p的'.*',如果要匹配多次就继续去判断i+1,j不变 两者有一个成功就行
            if(j<p.size()-1&&p[j+1]=='*'){
               res=dp(s,i,p,j+2)||dp(s,i+1,p,j);
            }else{
                //如果没有*存在
                res=dp(s,i+1,p,j+1);
            }
        }else{
            //如果匹配失败 也有可能是j+1位是*,匹配0次
            if(j<p.size()-1&&p[j+1]=='*')return dp(s,i,p,j+2);
            else{
                res=false;
            }
        }
        //写到这里可以发现其实是存在重叠子问题的,那么我们可以记录s的i位置和p的j位置判断时的结果
        memo[key]=res;//没有的话map会自己创建
        return res;
    }
};
posted @ 2022-05-11 09:08  BailanZ  阅读(44)  评论(0编辑  收藏  举报