传送门 https://leetcode-cn.com/problems/regular-expression-matching/
题目描述:
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 '.'
和 '*'
的正则表达式匹配。
'.' 匹配任意单个字符
'*' 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
示例:
输入:
s = “aa”
p = “a”
输出: false
解释: “a” 无法匹配 “aa” 整个字符串。
输入:
s = “aa”
p = “a“
输出: true
解释: 因为 ‘‘ 代表可以匹配零个或多个前面的那一个元素, 在这里前面的元素就是 ‘a’。因此,字符串 “aa” 可被视为 ‘a’ 重复了一次。
输入:
s = “ab”
p = “.“
输出: true
解释: “.“ 表示可匹配零个或多个(’*’)任意字符(’.’)。
输入:
s = “aab”
p ="c*a*b"
输出: true
解释: 因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0 个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。
输入:
s = “mississippi”
p ="mis*is*p*."
输出: false
题解:
自顶向下动态规划
推荐详细解析 https://leetcode-cn.com/problems/regular-expression-matching/solution/ji-yu-guan-fang-ti-jie-gen-xiang-xi-de-jiang-jie-b/1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37class Solution {
enum Result{
t,f
}
Result memo[][] = null;
public boolean isMatch(String s, String p) {
memo = new Result[s.length()+1][p.length()+1];
return dp(s, p, 0, 0);
}
public boolean dp(String s, String p, int i, int j)
{
if (memo[i][j] != null)
return memo[i][j] == Result.t;
boolean ans = false;
if (j == p.length()) // 当s,p长度都为0或者相等时
{
ans = (i == s.length());
}else // j < p.length()
{
boolean first_match = (i < s.length() &&
( s.charAt(i) == p.charAt(j) || p.charAt(j) == '.' ) );
if ( p.length() > j+1 && p.charAt(j+1) == '*' )
{
ans = ( dp(s, p, i, j+2) || first_match && dp(s, p, i+1, j) );
}else
{
ans = first_match && dp(s, p, i+1, j+1);
}
}
memo[i][j] = ans? Result.t : Result.f;
return ans;
}
}
自底向上动态规划
处理方法与自顶向下相似,不过需注意数组越界问题。此外,需注意&&
优先级大于||
,当&&
的左边为false时,程序不会执行&&
的右边,所以下面程序才不会出现越界。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25class Solution {
public boolean isMatch(String s, String p) {
int m = s.length(), n = p.length();
boolean[][] dp = new boolean[m+2][n+2];
dp[m][n] = true;
for (int i=m; i>=0; i--)
{
for (int j=n-1; j>=0; j--)
{
boolean first_match = i < m && s.charAt(i) == p.charAt(j) || p.charAt(j) == '.';
if (j < n-1 && p.charAt(j+1) == '*')
{
dp[i][j] = dp[i][j+2] || first_match && dp[i+1][j] ;
}else
{
dp[i][j] = first_match && dp[i+1][j+1];
}
}
}
return dp[0][0];
}
}
PS:题解来源于力扣官方题解