// 44.通配符匹配 dp专项训练 4.21每日一题
/*
* 给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。
* '?' 可以匹配任何单个字符。'*' 可以匹配任意字符串(包括空字符串)。
* 两个字符串完全匹配才算匹配成功。
* s 可能为空,且只包含从 a-z 的小写字母。
* p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。
* */
/*
* -------------------------------------------------------------
* 思路:
* dp[i][j]表示 截止到字符串s的第i个位置和字符串p的第j个位置,能否成功匹配
* dp[0][0]初始化为true,因为空字符串一定和空字符串匹配
* i和j代表的是真实下标,而不是数组下标。所以写程序的时候注意要-1的地方
* -------------------------------------------------------------
* 当p[j]=='?'时,dp[i][j] = dp[i-1][j-1]
* 当p[j]=='*'时,dp[i][j] = true(if 存在dp[i-X][j-1]==true ,X可以取0,1,2...s.length)
* else: dp[i][j] = false
* OtherWise:
* if(s[i]==p[j]) dp[i][j] = dp[i-1][j-1]
* else: dp[i][j] = false
* -------------------------------------------------------------
* 返回: dp[s.length][p.length]
* */
public class Solution44 {
public boolean isMatch(String s, String p) {
// 首先考虑特殊情况,s为空
if (s.length() == 0) {
//只要p里存在不为*的字符,就返回false,否则返回true
for (int i = 0; i < p.length(); i++) {
if (p.charAt(i) != '*')
return false;
}
return true;
}
// 特殊情况:p为空,只要s不为空,则返回false
if (s.length() != 0 && p.length() == 0)
return false;
int i = 0, j = 0;
boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
dp[0][0] = true;
dp[1][0] = false;
if (p.charAt(0) == '*') {
dp[0][1] = true;
// 特殊情况: p: [***h0]
// 要首先查看p开头有几个*
for (int i1 = 1; i1 < p.length(); i1++) {
if(p.charAt(i1) == '*'){
dp[0][i1+1]=true;
}else {
dp[0][i1+1]=false;
break;
}
}
} else
dp[0][1] = false;
// 初始化完毕,开始dp
for (i = 1; i < dp.length; i++) {
for (j = 1; j < dp[0].length; j++) {
if (p.charAt(j - 1) == '*') {
// 寻找是否存在dp[i-X][j-1]==true,如果存在,则dp[i][j] = true
int X;
for (X = 0; X <= i; X++) {
if (dp[i - X][j - 1] == true) {
dp[i][j] = true;
break;
}
}
if (X > i) {
dp[i][j] = false;
}
} else if (p.charAt(j - 1) == '?') {
dp[i][j] = dp[i - 1][j - 1];
} else {
// p[j]为其他字符的情况
if (s.charAt(i - 1) == p.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = false;
}
}
}
}
return dp[s.length()][p.length()];
}
}
DP专项训练:leetcode44.通配符匹配
最新推荐文章于 2022-07-08 20:27:39 发布