每日一题【LeetCode44】 通配符匹配 -动态规划

每日一题【LeetCode44】 通配符匹配 -动态规划

算法描述

动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可 行解。
每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。
若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。
如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其结果填入表中。
这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具有相同的填表格式。

1:题目描述

给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。
'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。
两个字符串完全匹配才算匹配成功。

2:测试案例

 测试案例1:

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

 测试案例2:

输入:
s = “aa”
p = " * "
输出: true
解释: ’ * ’ 可以匹配任意字符串。

测试案例3:

输入:
s = “cb”
p = “?a”
输出: false
解释: ‘?’ 可以匹配 ‘c’, 但第二个 ‘a’ 无法匹配 ‘b’。

测试案例4:

输入:
s = “adceb”
p = " * a * b"
输出: true
解释: 第一个 ’ * ’ 可以匹配空字符串, 第二个 ‘*’ 可以匹配字符串 “dce”.

测试案例5:

输入:
s = “acdcb”
p = “a*c?b”
输出: false

提示:

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

3:解题思路

和【LeetCode10-正则表达式匹配】类似,都可以采用动态规划算法进行求解,主要抓住的是字符串(S)的前i个和字符模式§前j个的匹配情况。最后判断字符串和匹配规则是否完全匹配。
1:如果字符串模式§ P[j-1] ==’?’ 表示p[j-1]一定和s[j-1]匹配,只需要另dp[i][j] = dp[i-1]j-1;
2:P[j-1]==p[i-1] 和 P[j-1]==’?’ 一致。
3:P[j-1]== ‘*’ 表示为空或者多个字符串,就可以dp[i][j] = dp[i-1][j]|dp[i][j-1]【dp[i-1][j] 是‘ * ’ 表示使用一个* 匹配S[i-1],dp[i][j-1] 是’ * ’ 为空的情况,也可以完全匹配。】;
最后是边界情况,如果第一个是*,或者一直是* , 也可以对S字符串进行全匹配。

4:代码解析

class Solution {
public:
	bool isMatch(string s, string p) {
		int row = s.size();
		int col = p.size();
		vector<vector<int>> dp(row + 1, vector<int>(col + 1, 0));//初始化背包
		dp[0][0] = 1;
		//边界问题
		for (int i = 0; i < col; ++i)
		{
			if (p[i] == '*')
				dp[0][i + 1] = true;
			else
				break;
		};
		//状态转移方程
		for (int i = 1; i <= row; ++i)
		{
			for (int j = 1; j <= col; ++j)
			{
				if (p[j - 1] == '*')
					dp[i][j] = dp[i][j - 1] | dp[i - 1][j]; //两个状态转移方程
				else if (p[j - 1] == '?' || p[j - 1] == s[i - 1])
					dp[i][j] = dp[i - 1][j - 1];//两个状态转移方程
			};
		};
		return dp[row][col];

	}
};

5:题目总结

本篇文章也是对动态规划的一个思考,对于未知,且拿到手上不知道的题目,需要刻苦专研,方可百炼成钢。对于动态规划的使用,我现在也不是特别清楚,该如何设计,该如何转移,后面我也将进行大量的刷题,能够使得自己对于动态规划达到一个使用流畅的程度。后面自己的博客将会优化。思路和总结概括,还有对状态背包的一个合理阐述。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值