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 lettersa-z
.p
could be empty and contains only lowercase lettersa-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 Submitted | Status | Runtime | Memory | Language |
---|---|---|---|---|
7 hours ago | Accepted | 4 ms | 8.2 MB | cpp |
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日 星期二