1 常见题目
1.1 (lee-JZ19) 正则表达式匹配
请实现一个函数用来匹配包含’. ‘和’‘的正则表达式。模式中的字符’.'表示任意一个字符,而’*'表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"和"aba"均不匹配。
输入: s = “aa” p = “a”
输出: false
解释: “a” 无法匹配 “aa” 整个字符串。
输入: s = “aab” p = “cab”
输出: true
解释: 因为 ‘*’ 表示零个或多个,这里 ‘c’ 为 0 个, ‘a’ 被重复一次。因此可以匹配字符串 “aab”。
public class RegularExpressionMatching {
/*
* state: f[i][j]表示 s 的前 i 个字符与 p 中的前 j 个字符是否能够匹配
* function: if(p[j]== '*') -- f(i,j) = f[i][j−2]
* if(p[j]!= '*') -- f(i,j) = f[i−1][j−1], matches(s[i],p[j])
* otherwise = f[i−1][j] or f[i][j−2],matches(s[i],p[j−1])
* f[i][j−2],otherwise
* 其中 matches(x,y)判断两个字符是否匹配的辅助函数。只有当y 是 . 或者 x 和 y 本身相同时,这两个字符才会匹配。
* initial:f(0,0) = true,两个空字符串是可以匹配的
* res:f(m,n)
* 时间复杂度:O(m*n)
* 空间复杂度:O(m*n)
*/
public boolean isMatch(String s, String p) {
int m = s.length();
int n = p.length();
boolean[][] f = new boolean[m+1][n+1];
f[0][0] = true;
for(int i = 0;i <= m;i++) {
for(int j = 1;j <= n;j++) {
if(p.charAt(j-1) == '*') {
f[i][j] = f[i][j-2];
if(maches(s,p,i,j-1)) {
f[i][j] = f[i][j] || f[i-1][j];
}
}else {
if(maches(s,p,i,j)) {
f[i][j] = f[i-1][j-1];
}
}
}
}
return f[m][n];
}
private boolean maches(String s, String p, int i, int j) {
if(i == 0) {
return false;
}
if(p.charAt(j-1) == '.') {
return true;
}
return s.charAt(i-1) == p.charAt(j-1);
}
}