给出text和pattern,pattern中可以使用通配符.和*,.表示匹配任意字符,*表示匹配上一个字符
从text和pattern的第一个字符开始做匹配
1.第一个字符匹配成功,要么第一个字符相等或者pattern的首字符为.
2.*字符只可能为pattern的开始匹配位置计数开始的第2个,如果第2个为*,
(1)直接路过pattern的前两个
(2)如果首字符匹配成功,则从text的下一个字符开始与pattern作匹配
3.如果首字符匹配成功,从text和pattern的下一个字符开始作匹配
递归代码如下:
class Solution(object):
def isMatch(self, s, p):
if not p:
return not s
firstmatch = bool(s) and p[0] in {s[0], '.'}
if len(p) >= 2 and p[1] == '*':
return (self.isMatch(s, p[2:]) or
firstmatch and self.isMatch(s[1:], p))
else:
return firstmatch and self.isMatch(s[1:], p[1:])
动态规划算法
用f(i,j)表示text[i:]和pattern[j:]是否匹配,则
f(i,j) = 模式串的开始的第2个字符为*时,f(i, j + 2),如果首字符匹配为f(i + 1, j)
具体代码如下:
enum Result
{
TRUE, FALSE
}
public class Solution
{
private Result[][] result;
public boolean isMatch(String s, String p)
{
result = new Result[s.length() + 1][p.length() + 1];
return dp(0, 0, s, p);
}
private boolean dp(int i, int j, String s, String p)
{
if (result[i][j] != null)
{
return result[i][j] == Result.TRUE;
}
boolean ans;
if (j == p.length())
{
ans = i == s.length();
}
else
{
boolean firstMatch = (i < s.length() && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '.'));
if (j + 1 < p.length() && p.charAt(j + 1) == '*')
{
ans = dp(i, j + 2, s, p) || (firstMatch && dp(i + 1, j, s, p));
}
else
{
ans = firstMatch && dp(i + 1, j + 1, s, p);
}
}
result[i][j] = ans ? Result.TRUE : Result.FALSE;
return ans;
}
}
动态规划的递推实现
func isMatch(s string, p string) bool {
var sLen int = len(s)
var pLen int = len(p)
var dp [][]bool
for i := 0; i < sLen + 1; i++ {
s1 := make([]bool, pLen + 1)
for j := 0; j < pLen + 1; j++ {
s1 = append(s1, false)
}
dp = append(dp, s1)
}
dp[sLen][pLen] = true
for i := sLen; i >= 0; i-- {
for j := pLen - 1; j >= 0; j-- {
var firstMatch bool = i < sLen && s[i] == p[j] || p[j] == '.'
if j + 1 < pLen && p[j + 1] == '*' {
dp[i][j] = dp[i][j + 2] || (firstMatch && dp[i + 1][j])
} else {
dp[i][j] = firstMatch && dp[i + 1][j + 1]
}
}
}
return dp[0][0]
}