题目描述:
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). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "a*") → true isMatch("aa", ".*") → true isMatch("ab", ".*") → true isMatch("aab", "c*a*b") → true
思路就是递归法,代码如下:
public boolean isMatch(String s, String p) {
if (p.length() == 0) {
return s.length() == 0;
}
if (p.length() > 1 && p.charAt(1) == '*') {
if (isMatch(s, p.substring(2))) {
return true;
}
if(s.length() > 0 && (p.charAt(0) == '.' || s.charAt(0) == p.charAt(0))) {
return isMatch(s.substring(1), p);
}
return false;
} else {
if(s.length() > 0 && (p.charAt(0) == '.' || s.charAt(0) == p.charAt(0))) {
return isMatch(s.substring(1), p.substring(1));
}
return false;
}
}
还有一种风格的递归:
public class Solution {
public boolean matches(String s,int sIndex,String p,int pIndex) {
if (pIndex == p.length()) {
return sIndex == s.length();
}
if (pIndex < p.length()-1 && p.charAt(pIndex+1) == '*') {
while (true) {
if (matches(s,sIndex,p,pIndex+2)) {
return true;
}
if (sIndex < s.length() && (s.charAt(sIndex)==p.charAt(pIndex) || p.charAt(pIndex)=='.')) {
sIndex++;
}
else {
return matches(s,sIndex,p,pIndex+2);
}
}
}
if (sIndex == s.length()) {
return false;
}
if (p.charAt(pIndex)=='.' || p.charAt(pIndex) == s.charAt(sIndex)) {
return matches(s,sIndex+1,p,pIndex+1);
}
return false;
}
public boolean isMatch(String s, String p) {
// try matching with asterisk
if (p == null || p.length()==0) return (s==null || s.length()==0);
return matches(s,0,p,0);
}
}
然而这个题最快的方法应该是用动态规划来优化算法:
public class Solution {
char[] s, p;
int sLength, pLength, noWildcard;
Boolean[][] dp;
public boolean isMatch(String ss, String ps) {
s = ss.toCharArray();
p = ps.toCharArray();
sLength = s.length;
pLength = p.length;
noWildcard = pLength - 1;
dp = new Boolean[pLength + 1][sLength + 1];
return isMatch(0, 0);
}
boolean isMatch(int pi, int si){
if(dp[pi][si] != null) return dp[pi][si];
while(true){
if(pi < noWildcard && p[pi+1] == '*'){
char c = p[pi];
pi += 2;
while(true){
boolean isMatch = isMatch(pi, si);
dp[pi][si] = isMatch;
if(isMatch){
return true;
}
if(si == sLength) return pi == pLength;
if(c != '.' && c != s[si]){
return false;
}
si++;
}
}
if(pi == pLength || si == sLength) return pi == pLength && si == sLength;
if(p[pi] != '.' && p[pi] != s[si]){
return false;
}
pi++;
si++;
}
}
}