题目:力扣
解题思路:
一开始用了递归来做,超时了
递归的思路:
1、当字符串和模式串为空时,直接返回true。
2、当字符串不为空但模式串为空时,返回false
3、当字符串为空时,模式串不为空,需要判断,如果模式串全为*,则返回true,否则返回false。
4、当字符串和模式串均不为空时,也需要判断。
先判断第一个字符是否相等
- 当两个字符相等时,相等
- 当模式串字符为?,无论字符串字符是什么,相等
当第一个字符相等时,返回isMatch(s.substring(1,s_len),p.substring(1,p_len)),只需要匹配剩下的就好。
当first不相等时,且模式串字符为*时,这时需要判断
- 当模式串只有一个*字符,直接返回true
- 当字符串为空,模式串长度大于1时,返回isMatch(s,p.substring(1,p_len))
- 其他的情况,直接返回isMatch(s.substring(1, s_len), p) || isMatch(s, p.substring(1, p_len)),前面的是*包含字符的情况,后面的是*代表空串的情况。
当first不相等时,当模式串的字符不为*,其实只是一个普通字母,则直接返回false。
动态规划的思路:
用dp[i][j]表示字符串前i个字符和字符串前j个字符是否匹配,匹配为true,否则为false
比较第i个和第j个字符
当相等,或者模式字符为?时, dp[i][j] = dp[i-1][j-1]。
当模式串字符为*时,dp[i][j] = dp[i-1][j] || dp[i][j-1]
class Solution {
public boolean isMatch(String s, String p) {
int s_len = s.length();
int p_len = p.length();
if(s_len == 0 && p_len == 0){
return true;
}
if(s_len != 0 && p_len == 0){
return false;
}
boolean first = false;
if(s_len != 0 && (s.charAt(0) == p.charAt(0) || p.charAt(0) == '?') ){
first = true;
}
if(first == true)
return isMatch(s.substring(1,s_len),p.substring(1,p_len));
else if(first == false && p.charAt(0) =='*'){
if(p_len == 1){
return true;
}
if(s_len == 0){
return isMatch(s, p.substring(1, p_len));
}
//这一步,计算有重复导致超时
return (isMatch(s.substring(1, s_len), p) || isMatch(s, p.substring(1, p_len)));
}
else
return false;
}
}
class Solution {
public boolean isMatch(String s, String p) {
int s_len = s.length();
int p_len = p.length();
boolean[][] dp = new boolean[s_len+1][p_len+1];
dp[0][0] = true;
for (int i = 1; i <= p_len; ++i) {
if (p.charAt(i - 1) == '*') {
dp[0][i] = true;
} else {
break;
}
}
for(int i = 1; i <= s_len; i++){
for(int j = 1; j <= p_len; j++){
if(s.charAt(i-1) == p.charAt(j-1) || p.charAt(j-1)=='?'){
dp[i][j] = dp[i-1][j-1];
}
else if(p.charAt(j-1) == '*'){
dp[i][j] = dp[i-1][j] || dp[i][j-1];
}
}
}
return dp[s_len][p_len];
}
}