leetcode 每日一题 44. 通配符匹配

动态规划

思路:

遍历模式串p每一个字符,用列表dp[i][j]统计模式串p中下标为i-1的字符能否匹配到字符串s中下标为j-1的字符。

列表初始状态dp[0][0]为True,接下来讨论p字符的三种情况,即 ‘ * ’ ,‘’,‘ 非*和?的字符

① 当p中第i个字符为 * 时,则先查看p中第i-1个字符和字符串s每一个字符的匹配情况,找到第一个匹配字符所对应字符串s的下标j,因为*可以匹配空字符串,则dp[i][j-1]=dp[i-1][j-1],又*可以匹配任意字符串,所以在字符串s从j开始到截止后面的字符均可以匹配。

② 当p中第i个字符为 ? 时, 则对于字符串s来说,从第一个字符开始,dp[i][j] = dp[i-1][j-1],因为 '?'可以匹配任意值,所以当前状态dp[i][j]跟前面状态dp[i-1][j-1]一致。

③ 当p中第i个字符不为'*' 和 '?' 时,则对于字符串s来说,从第一个字符开始,则dp[i][j] = dp[i-1][j-1] and p[i-1] = s[j-1],即如果前面状态不匹配,则后面也不会匹配,前面状态匹配了,后面字符相等的情况下,才会匹配。

例如:

s = ‘abcdef’  p =  ‘ a*d?f’

 

 

代码:

class Solution:
    def isMatch(self, s, p):
        s_len = len(s)
        p_len = len(p)
        if p == s or p == '*':
            return True
        if p == '' or s == '':
            return False
        d = [ [False] * (s_len + 1) for _ in range(p_len + 1)]
        d[0][0] = True
        for p_idx in range(1, p_len + 1):
            if p[p_idx - 1] == '*':
                s_idx = 1
                while not d[p_idx - 1][s_idx - 1] and s_idx < s_len + 1:
                    s_idx += 1
                d[p_idx][s_idx - 1] = d[p_idx - 1][s_idx - 1]
                while s_idx < s_len + 1:
                    d[p_idx][s_idx] = True
                    s_idx += 1
            elif p[p_idx - 1] == '?':
                for s_idx in range(1, s_len + 1): 
                    d[p_idx][s_idx] = d[p_idx - 1][s_idx - 1] 
            else:
                for s_idx in range(1, s_len + 1): 
                    d[p_idx][s_idx] = \
                    d[p_idx - 1][s_idx - 1] and p[p_idx - 1] == s[s_idx - 1]               
        return d[p_len][s_len]

猜你喜欢

转载自www.cnblogs.com/nilhxzcode/p/12966089.html