方法:有两个指针s和p,s指向字符串,p指向模式
1.首先我们分析出现'.'的情况,从题目中可以知道,这个符号可以代表任意一个字符,也就是这两个指针同时后移一位(或者是这两个字符相等)
2.当出现'*'的时候:
(1)当s和p相等(注意这个相等),p+1是‘*’的时候,会出现三种情况:
a.模式不变(也就是指针p不变),s向后移动一位。比如abbcd和ab*cf,其中s和p都指向了b。由于b出现了多次,应该不着急移动p,所以此时s+1即可。
b.忽略这个‘*’,p向后移动两位,s向后移动一位。比如abcd和ab*cf,其中s和p都指向了b。此时应该s+1和p+2
c.忽略这个'*’,p向后移动两位,s不变。比如"cba","cb*a*a",我也可以认为,p指向的第1个a没出现过,即使你相等。因此此时可以s不动,p+2(也就是直接跳到最后比较)。
(2)当s和p不相等的时候,p+1是‘*’的情况,相当于这个没出现,p向后移动两位。
由于把真正的相等和'.'标记的相等并成一类,就只用考虑'*'。如果不出现星号,就常规比较,常规比较肯定出现相等或者不等两类。如果出现星号,就考虑两个指针指的是否相等,不等,则p指针直接+2。两个指针相等,则有3种情况并列处理。再在这些判断中,加入对应边界条件,就可以很容易理解并写出代码了。
public class Solution { public boolean match(char[] str, char[] pattern) { if(str==null || pattern==null){ return false; } return match(str,0,pattern,0); } public boolean match(char[] str,int s,char[] pattern,int p){ if(s==str.length && p==pattern.length){ return true; } if(s<str.length && p==pattern.length){ return false; } //下一个指针指向的是* if(p+1<pattern.length && pattern[p+1]=='*'){ //出现了*号,并且s和p指的相同 if((s<str.length && pattern[p]=='.') || (s<str.length && str[s]==pattern[p] )){ return match(str,s,pattern,p+2) || match(str,s+1,pattern,p+2) || match(str,s+1,pattern,p); } else{ return match(str,s,pattern,p+2); } } //下一个不是* if(s<str.length&& (str[s]==pattern[p] || pattern[p]=='.')){ return match(str,s+1,pattern,p+1); } return false; } }
