10. 正则表达式匹配 Regular Expression Matching
Given an input string (s
) and a pattern (p
), implement regular expression matching with support for '.'
and '*'
where:
'.'
Matches any single character.'*'
Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).
Input: s = "aa", p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
方法一、递归
如果没有*,我们依次比较即可
如果存在*,由于题目要求,*是跟着某个字符后面,我们可以1 、忽略*和*前面的字符 2、s和 *前的字符相同,则匹配s剩下的字符和*前即可
public boolean isMatch(String text, String pattern){ if ( pattern.isEmpty() ) return text.isEmpty(); boolean first_match = (!text.isEmpty() && (pattern.charAt(0) == text.charAt(0) || pattern.charAt(0) == '.')); if (pattern.length() >= 2 && pattern.charAt(1) == '*'){ return (isMatch(text, pattern.substring(2)) ||(first_match && isMatch(text.substring(1), pattern))); }else{ return first_match && isMatch(text.substring(1), pattern.substring(1)); } }
方法二:动态规划
我们可以定义一个二维的 DP 数组,其中 dp[i][j] 表示 s[0,i) 和 p[0,j) 是否 match。
1. P[i][j] = P[i - 1][j - 1], if p[j - 1] != '*' && (s[i - 1] == p[j - 1] || p[j - 1] == '.');
2. P[i][j] = P[i][j - 2], if p[j - 1] == '*' and the pattern repeats for 0 times;
3. 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.
自底向上
enum Result { TRUE, FALSE } Result[][] memo; public boolean isMatch(String text, String pattern){ memo = new Result[text.length() + 1][pattern.length() + 1]; return dp(0, 0, text, pattern); } public boolean dp(int i, int j, String text, String pattern){ if(memo[i][j] != null){ return memo[i][j] == Result.TRUE; } boolean ans; if( j == pattern.length()){ ans = i == text.length(); }else{ boolean first_match = ( i < text.length() && (pattern.charAt(j) == text.charAt(i) || pattern.charAt(j) == '.')); if(j + 1 < pattern.length() && pattern.charAt(j+1) == '*'){ ans = (dp(i, j + 2, text, pattern) || first_match &&dp(I + 1, j, text, pattern)); }else{ ans = first_match && dp(i + 1, j +1, text, pattern); } } memo[i][j] = ans ? Result.TRUE : Result.FALSE; return ans; }
或者自顶向下
public boolean isMatch(String text, String pattern){ boolean [][] dp = new boolean[text.length() + 1][pattern.length() + 1]; dp[text.length()][pattern.length()] = true; for (int i = text.length(); i >= 0; i--){ for (int j = pattern.length() - 1; j>= 0; j--){ boolean first_match = (i < text.length() && (pattern.charAt(j) == text.charAt(i) || pattern.charAt(j) == '.')); if(j + 1 < pattern.length() && pattern.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]; }
参考链接:
https://leetcode.com/problems/regular-expression-matching
https://leetcode-cn.com/problems/regular-expression-matching