LeetCode系列之【44. 通配符匹配】C++ 每天一道leetcode!

目录(快速导航)

题目描述

视频讲解 https://www.bilibili.com/video/av66851964/

思路

代码


题目描述:

题目链接:https://leetcode-cn.com/problems/wildcard-matching/

给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。

'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。

两个字符串完全匹配才算匹配成功。

说明:

s 可能为空,且只包含从 a-z 的小写字母。
p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。
示例 1:

输入:
s = "aa"
p = "a"
输出: false
解释: "a" 无法匹配 "aa" 整个字符串。

视频讲解

https://www.bilibili.com/video/av66851964/


思路:

动态规划:

(一)状态

f[i][j]表示s1的前i个字符,和s2的前j个字符,能否匹配


(二)转移方程

如果s1的第 i 个字符和s2的第 j 个字符相同,或者s2的第 j 个字符为 “.”
f[i][j] = f[i - 1][j - 1]
如果s2的第 j 个字符为 *
若s2的第 j 个字符匹配空串, f[i][j] = f[i][j - 1]
若s2的第 j 个字符匹配s1的第 i 个字符, f[i][j] = f[i - 1][j]
这里注意不是 f[i - 1][j - 1], 举个例子就明白了 (abc, a*) f[3][2] = f[2][2]


(三)初始化

f[0][i] = f[0][i - 1] && s2[i] == *
即s1的前0个字符和s2的前i个字符能否匹配


(四)结果

f[m][n]

递归回溯

把所有可能全试一遍(超时)


代码:

动态规划

class Solution {
public:
    bool isMatch(string s, string p) {
        vector> dp(s.size()+1,vector(p.size()+1));
        dp[0][0] = 1;
        for (int j = 1;j <= p.size();j++) {
            dp[0][j] = dp[0][j - 1] && p[j-1] == '*';
        }
        for (int i = 1;i <= s.size();i++) {
            for (int j = 1;j <= p.size();j++) {
                if (p[j-1] == '*') {
                    dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
                }
                else {
                    dp[i][j] = (s[i-1] == p[j-1] || p[j-1] == '?') && dp[i - 1][j - 1];
                }
            }
        }
        return dp[s.size()][p.size()];
    }
};

回溯递归(超时)

class Solution {
public:
// 超时
bool isMatch(string s, string p) {
	if (p.empty()) return s.empty();
	if (s.empty()) {
		if (p[0] == '*') return isMatch(s, p.substr(1));
		else return false;
	}
	// 如果此时字符为*
	if (p[0] == '*') return isMatch(s, p.substr(1)) || isMatch(s.substr(1), p);
	else return (s[0] == p[0] || p[0] == '?') && isMatch(s.substr(1), p.substr(1));
}
};

一起加油!!刷题!!

你可能感兴趣的:(leetcode)