­

LeetCode10. Regular Expression Matching

  • 2019 年 11 月 9 日
  • 筆記

  題目:題目鏈接

  題意:給出兩個字符串s和p,問是否能夠完全匹配,其中s只包括小寫字母,p除了可能包括小寫字母外還含有字符’.’和’*’,’.’可以匹配任意字母,’*’表示其前面的那個字符可以有任意個(可以為0個)

  思路:類比LCS(最長公共子序列)問題,我們很容易想到該題的動態規劃解題思路。對於該題我們採用二維dp,dp[i][j]表示s前i個字符是否可以與p前j個字符完全匹配,遞推關係如下:

    1)  dp[0][0]=true;    

    2)  如果j > 1 && p[j – 1] == ‘*’:dp[i][j] = dp[i][j – 2] || (i > 0 && (s[i – 1] == p[j – 2] || p[j – 2] == ‘.’) && dp[i – 1][j]);

    3)  else :dp[i][j] = i > 0 && dp[i – 1][j – 1] && (s[i – 1] == p[j – 1] || p[j – 1] == ‘.’);

  PS:重新刷題立馬又感受到了英語對我深深的惡意,一開始又把題目讀錯了,以為只要s是p擴容後的子序列就行,直接導致第一次在leetcode上收穫熟悉的wrong answer一枚,看了題解才發現讀錯了題,我真是太沙雕了

  ac代碼如下:

 1 class Solution {   2 public:   3     bool isMatch(string s, string p) {   4         int n = s.size(), m = p.size();   5         vector< vector<bool> > ans(n + 1, vector<bool>(m + 1, false) );   6         ans[0][0] = true;   7         for(int i = 0; i <= n; ++i) {   8             for(int j = 1; j <= m; ++j) {   9                 if(j > 1 && p[j - 1] == '*')  10                     ans[i][j] = ans[i][j - 2] || (i > 0 && (s[i - 1] == p[j - 2] || p[j - 2] == '.') && ans[i - 1][j]);  11                 else  12                     ans[i][j] = i > 0 && ans[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');  13             }  14         }  15         return ans[n][m];  16     }  17 };