leetcode 44

44. 通配符匹配


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

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

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

说明:

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

  可以考虑使用和正则表达式一样的算法,但是会超时,它与正则表达式不一样的地方在于*可以匹配任意字符串

对于字符串s,p,指针分别为i,j从0开始,前面都一一匹配成功,当p出现*时,指针跳过*,比较i和j+1后续的匹配。若p又出现*,继续同样的操作,当出现不匹配时,i和j应该回到哪里继续匹配?正则表达式中是回到前一个*,让*匹配s中的一个,然后继续匹配,不匹配接着让*匹配两个,若*都匹配完了还是不匹配,就回到上上个*处,进行同样的操作,所以正则表达式采用的是迭代算法。

对于这道题,出现上述情况后,只用回到上一个*处就可以了,不用回到再之前的*去处理。所以只要记录上一个指针位置就可以了。这是为什么?请自行思考。

public boolean isMatch(String s, String p) {
		int i=0; int j=0; int match=0; int prem=-1;
		while(i<s.length()) {
			if(j<p.length()&&(s.charAt(i)==p.charAt(j)||p.charAt(j)=='?')) {
				i++;
				j++;
			}else if(j<p.length()&&p.charAt(j)=='*') {
				prem=j;
				match=i;
				j++;
			}else if(prem!=-1) {
				j=prem+1;
				i=match+1;
				match++;
			}else return false;
		}
		while(j<p.length()&&p.charAt(j)=='*') j++;
		return j==p.length();
	}

算了,还是提一下,对于s1="##ab###ab###@",p1="*ab*#"  当p1的两个*之间(包含*)的字符串匹配了s1 @之前的字符串的时候(第一个*匹配了##,第二个*匹配了###ab###),若p1的#和s1的@不匹配,若想增加第一个*匹配的字符串来达到匹配,那s1中必须存在第二个ab,第一个*需要匹配到第二个ab之前即##ab###,第二个*从后面三个###开始匹配,这里可以看到第一个*重新匹配的时候并不能包含最后一个ab之后的内容,也就是说那些部分都是第二个*匹配的字符串包含的。从始至终最后一个ab之后的内容都和第一个*无关,第二个*一直都要包含最后一个ab之后的内容,那对于ab之后的内容发生不匹配,显然第一个*是帮不上任何忙的。

如果不匹配发生在最后一个ab之前呢?s1="##ab###ab###@ab#", p1="*ab*#",同样@和#不匹配,这时候第一个*明显就可以修正这个不匹配。然而....这种情况第二个*也可以修正,干嘛要返回去增加时间复杂度,略略略~

有点罗嗦...

猜你喜欢

转载自blog.csdn.net/louiey/article/details/81146303