剑指52.正则表达式匹配
题目描述
请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配
思路
思路1:递归搜索。需要考虑到各种情况,并且时刻注意数组是否越界!
当pIndex当前位置的下一个位置是'*'时:
如果字符串第一个字符跟模式第一个字符不匹配,则模式后移2个字符,继续匹配。如果字符串第一个字符跟模式第一个字符匹配,可以有2种匹配方式:
- 1、模式后移2字符(相当于虽然匹配到了,仍然忽略); 举个例子:“abb” "ab*bb"
- 2、字符串后移1字符,模式不变,即继续匹配字符下一位,因为*可以匹配多位;
思路2:动态规划。
☆☆☆解法1
public class Solution { public boolean match(char[] str, char[] pattern){ if (str == null || pattern == null) return false; return matchCore(str,0,pattern,0); } private boolean matchCore(char[] str, int sIndex, char[] pattern, int pIndex) { // 递归终止条件1 if (sIndex == str.length && pIndex == pattern.length ) return true; // 递归终止条件2 if (sIndex == str.length || pIndex == pattern.length){ if (sIndex == str.length){ return help(pattern,pIndex); }else { return false; } } // pIndex当前字符的下一个位置的字符是* (放在前面可以通过 输入"a" ".*"的情况) if (pIndex + 1 < pattern.length && pattern[pIndex + 1] == '*'){ if (str[sIndex] == pattern[pIndex] || pattern[pIndex] == '.'){ // 匹配 return matchCore(str,sIndex,pattern,pIndex + 2) || matchCore(str,sIndex + 1,pattern,pIndex); // 最难的一步!! }else{ return matchCore(str,sIndex,pattern,pIndex + 2); } } // 当前两个下标所指的字符匹配 if (str[sIndex] == pattern[pIndex] || pattern[pIndex] == '.'){ return matchCore(str, sIndex + 1, pattern, pIndex + 1); } return false; // 不匹配 } // 处理 "aa" "aab*c*f*"这种情况 private boolean help(char[] pattern, int pIndex) { while (pIndex < pattern.length){ if (pIndex + 1 < pattern.length && pattern[pIndex + 1] == '*'){ pIndex += 2; }else{ return false; } } return true; } }