MENU

LeetCode10. Regular Expression Matching(动态规划)

2019 年 09 月 24 日 • 阅读: 2486 • LeetCode阅读设置

LeetCode10. Regular Expression Matching(动态规划)

  • Hard
  • Accepted:342,997
  • Submissions:1,334,578

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.

Example 1:

Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".

Example 2:

Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the preceding element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".

Example 3:

Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".

Example 4:

Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore, it matches "aab".

Example 5:

Input:
s = "mississippi"
p = "mis*is*p*."
Output: false

链接

https://leetcode.com/problems/regular-expression-matching/

题意

给定一个字符串s和一个模式串p,实现基于.*的正则表达式匹配。其中.可以匹配任意单个字符,*可以匹配零个或多个前面的字符。问模式串p是否能匹配整个字符串s。

题解

动态规划,$dp[i][j]$表示$s[0..i-1]$可以和$p[0..j-1]$完全匹配,那么有以下两种情况:

1. if s[i-1] == p[j-1] || p[j-1] == '.': dp[i][j] = dp[i-1][j-1]
2. if p[j-1] == '*':
        if p[j - 2] != '*' && p[j-2] != s[i-1]: dp[i][j] = dp[i][j-2] // 0a
        else: dp[i][j] = dp[i][j-2]   // 0a
              dp[i][j] = dp[i-1][j-2] // 1a
              dp[i][j] = dp[i-1][j]   // 1+a

对于初始化,$dp[0][0]$为true,dp[i][0]为false,而dp[0][j]的取值当p为#*#*#*或者(#*)*时为true。具体见代码。

参考:https://leetcode.com/problems/regular-expression-matching/discuss/5651/

代码

Time SubmittedStatusRuntimeMemoryLanguage
7 hours agoAccepted4 ms8.2 MBcpp
class Solution {
public:
    bool isMatch(string s, string p) {
        int n = s.length(), m = p.length();
        bool dp[n+1][m+1];
        memset(dp, 0, sizeof dp);
        dp[0][0] = true;
        for (int j = 2; j < m + 1; j += 2)
        {
            if (p[j - 1] == '*' && dp[0][j - 2])
                dp[0][j] = true;
        }
        for (int i = 1; i < n + 1; i++)
        {
            for (int j = 1; j < m + 1; j++)
            {
                if (s[i - 1] == p[j - 1] || p[j - 1] == '.')
                    dp[i][j] = dp[i - 1][j - 1];
                else if (p[j - 1] == '*')
                {
                    if (p[j - 2] != s[i - 1] && p[j - 2] != '.')
                        dp[i][j] = dp[i][j - 2];  
                    else
                        dp[i][j] = (dp[i - 1][j] || dp[i - 1][j - 2] || dp[i][j - 2]);
                }
            }
        } 
        return dp[n][m];
    }
};

The end.
2019年9月24日 星期二