LeetCode 44. Wildcard Matching (动归)

题目:

说明在注释中

class Solution {
public:
    bool isMatch(string s, string p) {
        /*
        //动态规划
        //想办法把转移方程写出来
        //先把所有可能情况全部列出来
        //d[0][0] = (p[0]=="?"||p[0]=="*"||p[0]==s[0]);
        //d[1][0] = (p[j]=="*"&&d[i-1][j]);
        //d[1][1] = (d[i-1][j-1] && (p[j]=="*"||p[j]=="?"||p[j]==s[i]))//前面的情况只要满足就不管他怎么满足,就顾着最后一个
        //d[0][1] = (p[j-1]=="*"&&(p[j]=="*"||p[j]=="*"||p[j]==s[i])&&d[i-1][j])
        //将最关键的几个列出来之后发现有些难整合,思考将d[1][0]和d[0][1]整合进d[1][1],那么就需要d[0][-1]和d[-1][0]的出现
        //然后我们其实可以想到忽略了一种情况,s="", p="*",所以两个空串可以作为d[0][0]
        //演进方程
        //d[0][0] = true;
        //d[1][0] = false;
        //d[0][1] = (p[1] == "*") *可以匹配空 
        //i和j从1开始遍历,所以p对应的应该是p[j-1]
        //d[i][j] = (d[i-1][j-1] && (p[j-1]=="*"||p[j-1]=="?"||p[j-1]==s[i-1]))
        //后来发现不满足 s="ab" p="*"情况,*可以无限匹配,以及  s="a" p="*a*"情况
		//添加方程  d[i][j] = (d[i-1][j] && p[j-1]=="*") ||(d[i][j-1] && p[j-1]=="*");
        //最终的方程
        // dp[i][j] = (dp[i-1][j-1] && (p[j-1]==anySeq[0]||p[j-1]==anyOne[0]||p[j-1]==s[i-1]));
        // if (dp[i][j] == 0) dp[i][j] = (dp[i-1][j] && p[j-1]==anySeq[0])||(dp[i][j-1] && p[j-1]==anySeq[0]);
        */


        //程序部分
        int sLen = s.length();
        int pLen = p.length();
        bool dp[sLen + 5][pLen + 5];
        memset(dp, 0, sizeof(dp));
        string anySeq = "*";
        string anyOne = "?";
        //初始化
        dp[0][0] = true;
        if(sLen >= 1) dp[1][0] = false; //其实这行不写也行 
        //如果是*或是连续的*都可以匹配空
		for(int j = 1; j <= pLen; j++){
			if(p[j-1] != anySeq[0]) break;
			dp[0][j] = true;
		}
        //填充矩阵
        for(int i = 1; i <= sLen; i++){
            for(int j = 1; j <= pLen; j++){
                dp[i][j] = (dp[i-1][j-1] && (p[j-1]==anySeq[0]||p[j-1]==anyOne[0]||p[j-1]==s[i-1]));
                if (dp[i][j] == 0) dp[i][j] = (dp[i-1][j] && p[j-1]==anySeq[0])||(dp[i][j-1] && p[j-1]==anySeq[0]);
            }
        }
        return dp[sLen][pLen];
    }
};

 

根据上面的情况举个例子验证我们的dp二维数组是否满足我们的期望:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_我走路带风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值