标签:
https://leetcode.com/problems/regular-expression-matching/
Implement regular expression matching with support for ‘.‘
and ‘*‘
.
‘.‘ Matches any single character. ‘*‘ Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). The function prototype should be: bool isMatch(const char *s, const char *p) Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "a*") → true isMatch("aa", ".*") → true isMatch("ab", ".*") → true isMatch("aab", "c*a*b") → true
解题思路:
好吧,这题是做leetcode来最难的题目之一,我承认自己不会。只能看别人的解法,总结如下。
本题的难度主要在p中的*上,因为如果p当前字符是字母,可以直接和s匹配,判断是否继续,如果是‘.‘,也可以和s的任何字符匹配,判断是否继续。但如果p当前是*,就要看p的前一个字符在s中到底能代表多少个?事实上,这个很难有方法来确定,只能枚举,可能是1个、2个或3个。这个问题在最后参考网址的第一个里有例子。
所以本题的思路大体可以分为两大块。
1. p的下一个字符不是*。此时我们可以大胆判断s和p的当前字符是否匹配(这里包含了p当前为‘.‘的情况)。如果匹配,则s和p各前进一个字符,继续判断;如果不匹配,则可以直接返回false。
2. p的下一个字符是*。
2.1 s和p的当前字符不匹配,s不动,p跳过本字符和下一个‘*‘,继续判断。就像题目里最后一个例子。
2.2 s和p的当前字符匹配(这里包含了p当前为‘.‘的情况),假设为‘x‘。我们要看p的下一个*到底在s里代表了几个‘x‘?于是,s按步长为1往后移动,判断p跳过本字符和下一个‘*‘之后的部分,和s往后的部分是否匹配。只要有一个匹配的可能性,就可以返回true了。
当然,这里s往后移动的范围必须在连续的N个‘x‘内,或者p还是‘.‘。
public class Solution { public boolean isMatch(String s, String p) { return isMatchHelper(s, p, 0, 0); } public boolean isMatchHelper(String s, String p, int i, int j) { //p已经结束,此时s也结束,就返回true if(j >= p.length()){ return i >= s.length(); } //p到了最后一个字符,s必须也是最后一个字符,并且两者相等(此时p不可能是*,因为*总是和它的前一个字符一起被跳过的) if(j == p.length() - 1) { return (i == s.length() - 1) && (s.charAt(i) == p.charAt(j) || p.charAt(j) == ‘.‘); } //1.如果p的下一个字符不是*,如果s和p的当前字符能匹配,就继续往下,不匹配直接返回false if(p.charAt(j + 1) != ‘*‘) { //但是此时s已经匹配结束了,返回false if(i == s.length()) { return false; } if(p.charAt(j) == ‘.‘) { return isMatchHelper(s, p, i + 1, j + 1); } return s.charAt(i) == p.charAt(j) && isMatchHelper(s, p, i + 1, j + 1); } //2.如果p的下一个字符是*,即p.charAt(j + 1) == ‘*‘ //2.1 如果s和p当前字符相等,或者p当前为. if(i < s.length() && (s.charAt(i) == p.charAt(j) || p.charAt(j) == ‘.‘)) { //在s.charAt(i) == p.charAt(j)的前提下,尝试s往后取1个、2个、3个...相同的字符,看后面只要匹配一种情况就可以 while(i < s.length() && (s.charAt(i) == p.charAt(j) || p.charAt(j) == ‘.‘)) { if(isMatchHelper(s, p, i, j + 2)) { return true; } i++; } } //2.2 p的下一个字符为*,且当前不为.,s和p当前字符不等,就直接跳过p的两个字符往后比较,比如题目中最后一个例子 // if(s.charAt(i) != p.charAt(j) && p.charAt(j) != ‘.‘) { return isMatchHelper(s, p, i, j + 2); // } } }
http://articles.leetcode.com/2011/09/regular-expression-matching.html
http://blog.csdn.net/fightforyourdream/article/details/17717873
http://blog.csdn.net/linhuanmars/article/details/21145563
标签:
原文地址:http://www.cnblogs.com/NickyYe/p/4376602.html