解题思路
思路是动态规划。
假设s是待匹配字符串,p是表达式。定义数组matchs,其中matchs[i,j]表示s[0,i)和p[0,j)是否匹配,那么结果就是求matchs[s长度加1,p长度加1]。
对于matchs[i,j]分以下情况:
- i=0,j=0,空的肯定能匹配
- i=0,j!=0,那么在j>1的情况下且p[j-1]是星号的时候,match[0,j]=match[0,j-2],相当于是.*结尾,可以匹配空串
- i>0,j>1,如果p[j-1]是星号,且前一个字符是.或者和s[i-1]一样,那么matchs[i,j] = matchs[i - 1,j] || matchs[i,j - 2],相当于是.或者a,可以匹配空串或最后一个字符
- 否则p[j-1]是.或者和s[i-1]一样,那么matchs[i,j] = matchs[i - 1,j - 1],相当于匹配最后一个字符
- 其他情况都是不匹配的。
参考源码
public class Solution {
public boolean isMatch(String s, String p) {
//match[i,j] = match result of s[0,i) and p[0,j).
boolean[][] matchs = new boolean[s.length() + 1][p.length() + 1];
matchs[0][0] = true;
//init the match result of 'empty s' and p.
for (int j = 1; j < p.length() + 1; j++) {
if (j > 1) {
//.* or a*
if (p.charAt(j - 1) == '*') {
matchs[0][j] = matchs[0][j - 2];
}
}
}
for (int i = 1; i < s.length() + 1; i++) {
char s1 = s.charAt(i - 1);
for (int j = 1; j < p.length() + 1; j++) {
char p2 = p.charAt(j - 1);
//.* or a*
if (j > 1 && p2 == '*') {
char p1 = p.charAt(j - 2);
if (p1 == '.' || p1 == s1) {
matchs[i][j] = matchs[i - 1][j] || matchs[i][j - 2];
} else {
matchs[i][j] = matchs[i][j - 2];
}
}
//. or a
else if (p2 == '.' || p2 == s1) {
matchs[i][j] = matchs[i - 1][j - 1];
}
}
}
return matchs[s.length()][p.length()];
}
}