题目:给定一个字符串 (s) 和一个字符模式 (p)。实现支持 ‘.’ 和 ‘*’ 的正则表达式匹配。
‘.’ 匹配任意单个字符。
‘*’ 匹配零个或多个前面的元素。
匹配应该覆盖整个字符串 (s) ,而不是部分字符串。
说明:
s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 . 和 *。
语言:java
我用的方法是递归,str和pattern各自设置下标,思路是大体分两种情况,一种是pattern的下一个字符为星号,一种是不为星号。区别在于下一次递归的下标参数不一样。
private String str = "";
private String pattern = "";
public boolean isMatch(String s, String p) {
// 考虑几个特殊样例,比如两个都为空,pattern为空。
if (s.equals(p)) {
return true;
}
if (p.equals("")) {
return false;
}
str = s;
pattern = p;
return match(0, 0);
}
public boolean match (int index1, int index2) {
boolean indexLast1 = index1 >= str.length();
boolean indexLast2 = index2 >= pattern.length();
// 当匹配到两个字符串的下标都到底的时候,匹配成功
if (indexLast1 && indexLast2) {
return true;
}
if (!indexLast1 && indexLast2) {
return false;
}
// 第一种情况:pattern的下一个字符为*号时
if (index2+1 < pattern.length() && pattern.charAt(index2+1) == '*') {
if (indexLast1) {
return match(index1, index2+2);
}
if (str.charAt(index1) == pattern.charAt(index2) || pattern.charAt(index2) == '.') {
// 匹配str的下一个字符或者抛弃这个星号去匹配pattern下一个模式
return match(index1+1, index2) || match(index1, index2+2);
} else {
return match(index1, index2+2);
}
}
if (indexLast1 && !indexLast2) {
return false;
}
// 第二种情况:pattern的下一个字符不为*,直接匹配单个字符
if (str.charAt(index1) == pattern.charAt(index2) || pattern.charAt(index2) == '.') {
return match(index1 + 1, index2 + 1);
}
return false;
}
为什么要在里面考虑indexLast1,就是当str的下标到底的时候呢,因为当str的下标到底时,pattern可能还有a*b*c*,这种情况也是匹配成功的,所以不能在开头就断定当indexLast1且!indexLast2的时候就匹配不成功。
而为了str不会访问越界,判定indexLast的条件要放在第一种情况和第二种情况的开头。
这种解法通过LeetCode(中国)于18年4月29日,用时71ms。(转载请标明出处)