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. };  
posted @ 2020-09-25 17:44  sheeeeeeep  阅读(123)  评论(0编辑  收藏  举报