小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目
请实现一个函数用来匹配包含'. '和''的正则表达式。模式中的字符'.'表示任意一个字符,而''表示它前面的字符可以出现任意次(含0次)。在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"abaca"匹配,但与"aa.a"和"ab*a"均不匹配。
示例 1:
输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。
来源:力扣(LeetCode)
难度:hard
思路
1.创建一个(m+1)*(n+1)大小的二维dp数组dp[i][j],其中i表示在s中的匹配进度,j表示在p中的匹配进度。
2.其中dp中的i,j对应chars1(s的字符数组),chars2(p的字符数组)中的i-1,j-1,这个一定要注意
3.计算时分为当前位置为 * 和当前位置不为*的情况
if (chars2[j - 1] == '*') {
注意根据2来看chars2[j-1]指的就是当前位置
代码
class Solution {
char[] chars1;
char[] chars2;
public boolean isMatch(String s, String p) {
chars1 = s.toCharArray();
chars2 = p.toCharArray();
int m = s.length();
int n = p.length();
boolean[][] dp = new boolean[m + 1][n + 1];
dp[0][0] = true; //都为空的情况下默认为true
for (int i = 0; i <= m; i++) {
for (int j = 1; j <= n; j++) {
if (chars2[j - 1] == '*') {
dp[i][j] = dp[i][j - 2]; //可以把*+前一个字符看成一个整体,那么向看在这个整体之前的字符匹配情况
if (isMatch(i, j - 1)) { //看*号前面那个字符的匹配情况
dp[i][j] = dp[i][j] || dp[i - 1][j]; //dp[i-1][j]是指*前面的字符被多次利用的情况
}
} else {
if (isMatch(i, j)) { //先看i位置和j位置是否匹配,不匹配的话就用默认值false
dp[i][j] = dp[i - 1][j - 1]; //匹配的话就是看dp[i-1][j-1]的结果
}
}
}
}
return dp[m][n];
}
public boolean isMatch(int i, int j) { //由于dp中的i,j一直比chars1,chars2中的大1
if (i <= 0) return false; //这种i没有东西匹配直接返回false
if (chars2[j - 1] == '.') { //啥都能匹配
return true;
}
return chars1[i - 1] == chars2[j - 1];
}
}