LeetCode-44.通配符匹配、动态规划算法的应用

给定一个字符串 (s) 和一个字符模式 § ,实现一个支持 ‘?’ 和 ‘’ 的通配符匹配。’?’ 可以匹配任何单个字符。’’ 可以匹配任意字符串(包括空字符串)。两个字符串完全匹配才算匹配成功。说明: s 可能为空,且只包含从 a-z 的小写字母。p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。
力扣(LeetCode)第44题

确定状态

  动态规划一般来讲,目标是求什么则什么即为状态,然后分析当前状态和之前状态的推导关系,进而进行穷举所有状态即可。
  本题中用 dp[i][j] 表示 s 以 i 位置结尾和 p 以 j 位置结尾时的匹配情况。

状态转移方程

根据题目要求,p 中字符有三种匹配情况:
①.p[j] == ‘?’
  ‘?’ 可以匹配任意单个字符,此时 dp[i][j] = dp[i-1][j-1]。
②.p[j] == ‘a-z’
  此时若 s[i-1] = p[j-1],则 dp[i][j] = dp[i-1][j-1]。
③.p[j] == *
  因为 * 可以匹配任意数量的任意字符,则有两种情况:
   * 匹配 0 个字符,则 dp[i][j] = dp[i][j-1];
   * 匹配 多个字符,则 dp[i][j] = dp[i-1][j];

边界及状态初始化

  • 增加相同开头字符
    为方便处理边界情况,使字符串下标 1 开始遍历,在 s 和 q 开头均增加相同字符 ‘a’ ,此时 dp[0][0] = 1。
  • 边界条件
    在上述的状态转移方程中,由于 dp[i][j] 对应着 s 的前 i 个字符和 p 的前 j 个字符,因此所有的所有的 dp[0][j]、dp[i][0] 都是边界条件。
    因为 p[0] 不为 ‘’,所以 dp[i][0] 始终为不匹配;
    只有当 p[j] =’
    ’ 时,dp[0][j] = dp[0][j-1]。

确认结果

  s 和 p 最末位置的匹配结果就是本题的结果,即 dp[s.size()-1][p.size()-1]。

代码示例

class Solution {
public:
    bool isMatch(string s, string p) {
        s= 'a'+s;
        p= 'a'+p;
        vector<vector<int>> dp(s.size(),vector(p.size(),0));//dp[i][j] 表示以i、j结尾的匹配情况
        dp[0][0] = 1;  
        for(int j = 1;j < p.size();j++)
        {
            if( p[j] == '*')
            {
                dp[0][j] = dp[0][j-1];
            }
        }
        for(int i = 1;i < s.size();i++)
        {
            dp[i][0] = 0;
        }
        for(int i = 1;i < s.size();i++)
        {
            for( int j = 1;j < p.size();j++)
            {
                if( p[j] == '?')
                {
                    dp[i][j] = dp[i-1][j-1];
                }
                else if( p[j] == '*')
                {
                    dp[i][j] = dp[i][j-1] || dp[i-1][j];
                }
                else 
                {
                    if( s[i] == p[j] )
                    {
                        dp[i][j] = dp[i-1][j-1];
                    }
                }
            }
        }
        return dp[s.size()-1][p.size()-1];
    }
};

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值