题目描述(困难难度)
字符串匹配,? 匹配单个任意字符,* 匹配任意长度字符串,包括空串。和第 10 题有些类似。
解法一 动态规划
直接按照之前第10 题,修改一下就可以了。
同样是用 dp[i][j]
表示所有的情况,然后一层一层的根据递推关系求出来。
举个例子
s=“acdcb”’
p=“a*c?b”
a | * | c | ? | b | ||
---|---|---|---|---|---|---|
a | T | F | F | F | F | F |
c | F | T | T | F | F | F |
d | F | F | T | T | F | F |
c | F | F | T | F | T | F |
b | F | F | T | T | F | F |
F | F | T | F | T | F |
首先将S的第一个元素与P所有元素进行匹配。
for(int pi=1;pi<=p.length();pi++){
if(p.charAt(pi-1)=='*'){
match[0][pi]=match[0][pi-1];
}
}
接着,分两种情况进行判断
- 如果S的前一个元素和P的前一个元素相等或者P的前一个元素等于?,那么
match[i][j]=match[i-1][j-1]
- 如果P的前一个元素等于*,那么
match[i][j]=match[i-1][j] || match[i][j-1];
具体代码如下:
class Solution {
public boolean isMatch(String s, String p) {
if(s==null || p==null) return false;
boolean[][] match = new boolean[s.length()+1][p.length()+1];
match[0][0]=true;
for(int pi=1;pi<=p.length();pi++){
if(p.charAt(pi-1)=='*'){
match[0][pi]=match[0][pi-1];
}
}
for(int si=1;si<=s.length();si++){
for(int pi=1;pi<=p.length();pi++){
if(s.charAt(si-1) == p.charAt(pi-1) || p.charAt(pi-1) =='?'){
match[si][pi]=match[si-1][pi-1];
}else if(p.charAt(pi-1)=='*'){
match[si][pi]=match[si-1][pi] || match[si][pi-1];
}
}
}
return match[s.length()][p.length()];
}
}
Python
class Solution(object):
def isMatch(self, s, p):
if(s==None or p==None):
return False
match =[[False] * (len(p)+1) for _ in range(len(s) + 1)]
match[0][0]=True
for pi in range(1,len(p)+1):
if(p[pi-1]=='*'):
match[0][pi]=match[0][pi-1]
for si in range(1,len(s)+1):
for pi in range(1,len(p)+1):
if(s[si-1] == p[pi-1] or p[pi-1] =='?'):
match[si][pi]=match[si-1][pi-1]
elif(p[pi-1]=='*'):
match[si][pi]=match[si-1][pi] or match[si][pi-1]
return match[len(s)][len(p)]
参考文献
- https://www.youtube.com/watch?v=9OnS06RYQiw