zoukankan      html  css  js  c++  java
  • leetcode之路:10. 正则表达式匹配

    题目传送门:https://leetcode-cn.com/problems/regular-expression-matching/

    看懂标准题解后AC了此题,看的时候觉得很难理解,这里我尝试解释得更通俗易懂一些。

    题解用了动态规划的思想,即直接求解一定规模的问题很难思考,但该问题可以转化为一个或几个更小规模的同类问题去解决。

    我们使用 bool dp[i][j] 来代表 s 串的前 i 个字符是否与 p 串的前 j 个字符相匹配,注意,这里是前 i 个字符,即 dp[i][j] 是 s[0 ... i - 1] 与 p[0 ... j - 1] 是否匹配。

    该问题可以分成以下两种情况:

      1: p 串最后一个字符不是 * 的情况:

        此时我们只需考虑 s[i - 1] 与 p[j - 1] 是否匹配即可(注意,这里的匹配有两层含义:s[i - 1] == p[j - 1] 或者 p[j - 1] == .)。如果匹配的话,则dp[i][j] = dp[i - 1][j - 1].

    参考如下代码:

    if(p[j - 1] != '*')dp[i][j] = (match(i, j) ? dp[i - 1][j - 1] : false);

      2: p串最后一个字符是 * 的情况:

        此时又可以分成两种情况:  

    •  这个 * 当 0 个前面的字符使用:此时这个 * 和前面的字符相当于都没了,dp[i][j] = dp[i][j - 2].
    •     这个 * 当任意个( > 0) 前面的字符使用:此时,如果有s[i - 1] 与 p[j - 2] 匹配,则 dp[i][j] = dp[i - 1][j].(这里可能会有疑问,比如我:不应该是 dp[i][j] = dp[i - 1][j - 1]吗?因为 p 串的最后一个字符 * 被匹配走了呀。  答:这个 * 不一定只匹配了 s 的最后一个字符,有可能 s 的倒数第二个、倒数第三个....都是这个 * 匹配的,所以这里 dp[i][j] = dp[i - 1][j] 是合理的。) 

    参考如下代码:

    if(match(i, j - 1))dp[i][j] =  dp[i - 1][j] || dp[i][j - 2];
    else dp[i][j] = dp[i][j - 2];

    完整代码如下:

    1. class Solution {  
    2. public:  
    3.     bool isMatch(string s, string p) {  
    4.         int s_len = s.size(), p_len = p.size();  
    5.         function<bool(intint)> match = [&](int i, int j){  
    6.             if(!i)return false;//这里不用管 j 是因为遍历数组时 j 从 1 开始   
    7.             return p[j - 1] == '.' || s[i - 1] == p[j - 1];  
    8.         };   
    9.         vector<vector<int>> dp(s_len + 1, vector<int>(p_len + 1));  
    10.         dp[0][0] = true;  
    11.         for(int i = 0; i <= s_len; i++){  
    12.             for(int j = 1; j <= p_len; j++){  
    13.                 if(p[j - 1] != '*')dp[i][j] = (match(i, j) ? dp[i - 1][j - 1] : false);  
    14.                 else{  
    15.                     if(match(i, j - 1))dp[i][j] =  dp[i - 1][j] || dp[i][j - 2];  
    16.                     else dp[i][j] = dp[i][j - 2];  
    17.                 }  
    18.             }  
    19.         }   
    20.         return dp[s_len][p_len];   
    21.     }  
    22. };  
  • 相关阅读:
    分层图最短路(DP思想) BZOJ2662 [BeiJing wc2012]冻结
    动态规划 BZOJ1925 地精部落
    线性DP SPOJ Mobile Service
    线性DP codevs2185 最长公共上升子序列
    数位DP POJ3208 Apocalypse Someday
    线性DP POJ3666 Making the Grade
    杨氏矩阵 线性DP? POJ2279 Mr.Young's Picture Permutations
    tarjan强连通分量 洛谷P1262 间谍网络
    树链剖分 BZOJ3589 动态树
    二分图 BZOJ4554 [Tjoi2016&Heoi2016]游戏
  • 原文地址:https://www.cnblogs.com/peichaoL/p/13731535.html
Copyright © 2011-2022 走看看