【leetcode】44. (Medium) WildCard Matching

题目链接


解题思路:
这道题的意思就是字符串匹配,s是正常的字符串,p是带有特殊字符的字符串,在p中,’?‘可以匹配任意一个字符,’*'可以匹配任意长度(包括0)的字符。
这道题可以用DP来做。(初始答案在题目后面的Description里)

首先动态规划的特点是会求得所有过程中的结果。
具体做法:
设s=adceb  p=* a* b 我们先创建一个boolean二维数组match,行数为s.length+1,用于存放s字符串;宽为p.length+1,用于存放p字符串;
在这里插入图片描述
在这里插入图片描述数组中任意一个value的值表示的是当前行及以下的s和当前列及以后的p的字符串是否匹配,如果两个方框所示。所以这里DP的方法是从尾匹配到头

现在说明匹配过程:
首先match[s.length][p.length]=true
在这里插入图片描述
然后对于最后一排,满足:

if(p.charAt(i)==’*’)
match[s.length()][i]=true;

就是最后一排,从后到前开始算,遇到p字符串的内容是’*'的话,值是true,这里p字符串的后面没有 ’ * ',所以最后一排的其他数值不做处理,直接跳到倒数第二行。

对于剩下的部分,只对中间部分进行计算,最后一列不做处理:
在这里插入图片描述

对于中间部分处理的顺序是,从最后一排的尾处理到头、从倒数第二排的尾处理到头、…
在这里插入图片描述


对于这些内容,处理的规则是:

 if(s.charAt(i)==p.charAt(j)||p.charAt(j)=='?')
					  match[i][j]=match[i+1][j+1];
				  else if(p.charAt(j)=='*')
					  match[i][j]=match[i+1][j]||match[i][j+1];
				  else
					  match[i][j]=false;

即分为三种情况,第一种:s[i]和p[j]字符是相同的
此时3处的数值match[i][j]取决于右下方的数值match[i+1][j+1]:
在这里插入图片描述

第二种,p[j]==’*’:
此时只要match[i][j]的右边是true或者下边是true,自己就是true:
在这里插入图片描述

第三种情况,s[i]!=p[j]:
直接false
在这里插入图片描述

根据这个规则可以填满所有的地方:

*a*b-
atruetruetruefalse
dfalsefalsetruefalse
cfalsefalsetruefalse
efalsefalsetruefalse
bfalsefalsetruetrue
-true

同时,match[0][0]就是最终的答案:
在这里插入图片描述
这个过程其实将所有过程中的答案都给了出来,符合DP的特点,比如下图中:
在这里插入图片描述

这个值的意思是" c e b “和” * b "字符串是匹配的

在这里插入图片描述
这个值表示"dceb"和"* a* b"是不匹配的


提交代码:

class Solution{
	  public boolean isMatch(String s, String p) {
		  boolean match[][]=new boolean[s.length()+1][p.length()+1];
		  match[s.length()][p.length()]=true;
		  
		  for(int i=p.length()-1;i>=0;i--) {
			  if(p.charAt(i)=='*')
				  match[s.length()][i]=true;
			  else break;
		  }
		  
		  for(int i=s.length()-1;i>=0;i--) {
			  for(int j=p.length()-1;j>=0;j--) {
				  if(s.charAt(i)==p.charAt(j)||p.charAt(j)=='?')
					  match[i][j]=match[i+1][j+1];
				  else if(p.charAt(j)=='*')
					  match[i][j]=match[i+1][j]||match[i][j+1];
				  else
					  match[i][j]=false;
			  }
		  }
		  
		  return match[0][0];
	  }
}

运行结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值