美文网首页
10. Regular Expression Matching

10. Regular Expression Matching

作者: xingzai | 来源:发表于2019-05-12 01:04 被阅读0次

题目链接
tag:

  • Hard;
  • DP;

question:
  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 precedeng 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 = "cab"
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 = "misisp*."
Output: false

思路:
  DP来解,定义一个二维的DP数组,其中dp[i][j]表示s[0,i)和p[0,j)是否match,然后有下面三种情况:

  • P[i][j] = P[i - 1][j - 1], if p[j - 1] != '*' && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
  • P[i][j] = P[i][j - 2], if p[j - 1] == '*' and the pattern repeats for 0 times;
  • P[i][j] = P[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.'), if p[j - 1] == '*' and the pattern repeats for at least 1 times.

C++ 解法:

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.size(), n = p.size();
        vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
        dp[0][0] = true;
        for (int i = 0; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (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]);
                } else {
                    dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
                }
            }
        }
        return dp[m][n];
    }
};

Python 解法:

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        dp = []
        defaultRow = [False] + [False for _ in p]
        dp.append(list(defaultRow))
        dp[0][0] = True
        for x in range(len(p)):
            if p[x] == '*':
                dp[0][x+1] = dp[0][x-1]

        for i in range(len(s)):
            dp.append(list(defaultRow))
            for j in range(len(p)):
                if p[j] != '*':
                    if (s[i] == p[j] or p[j] == '.') and dp[i][j]:
                        dp[i+1][j+1] = True
                elif p[j] == '.':
                    if dp[i][j]:
                        dp[i+1][j+1] = True
                else: # *
                    #匹配0次
                    if dp[i+1][j-1]:
                        dp[i+1][j+1] = True
                    #匹配1次
                    if dp[i+1][j]:
                        dp[i+1][j+1] = True
                    #匹配多次
                    if (s[i] == p[j-1] or p[j-1] == '.') and dp[i][j+1]:
                        dp[i+1][j+1] = True
        return dp[-1][-1]

相关文章

网友评论

      本文标题:10. Regular Expression Matching

      本文链接:https://www.haomeiwen.com/subject/hcdqaqtx.html