原题链接在这里: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
题解:
When it comes to two string, two array, with fixed position, asking count, max, min, true or false. It is likely to be dp.
Let dp[i][j] denotes matching result between s till index i-1 and p till index j-1.
最后返回dp[s.length()][p.length()]. 所以dp生成时要设size成new boolean[s.length()+1][p.length()+1].
状态转移时 如果当前的char能match上, dp[i][j] = dp[i-1][j-1].
否则的话如果p的当前char是'*', 要看p的前个char能否和s的当前char match上. 不能的话,这个'*'只能代表0个字符. dp[i][j] = dp[i][j-2].
如果能match上的话, 既可以代表0个字符 dp[i][j-2] 也可以代表多个字符 dp[i-1][j]. dp[i][j] = dp[i][j-2] || dp[i-1][j].
Time Complexity: O(m*n). m = s.length(), n = p.length().
Space: O(m*n).
AC Java:
1 public class Solution { 2 public boolean isMatch(String s, String p) { 3 int m = s.length(); 4 int n = p.length(); 5 boolean [][] dp = new boolean[m+1][n+1]; 6 dp[0][0] = true; 7 8 for(int j = 1; j<=n; j++){ 9 if(p.charAt(j-1) == '*'){ 10 dp[0][j] = dp[0][j-2]; 11 } 12 } 13 14 for(int i = 1; i<=m; i++){ 15 for(int j = 1; j<=n; j++){ 16 char sChar = s.charAt(i-1); 17 char pChar = p.charAt(j-1); 18 //若是首字符match 19 if(sChar == pChar || pChar == '.'){ 20 dp[i][j] = dp[i-1][j-1]; 21 }else if(pChar == '*'){ //pattern 末尾是 * 22 //pattern * 前一个char 和 pChar match, 可以是贪婪性减掉string的最后一char 23 if(sChar == p.charAt(j-2) || p.charAt(j-2) == '.'){ 24 dp[i][j] = dp[i][j-2] | dp[i-1][j]; 25 }else{ 26 //pattern * 前一个 char 和pChar match不上,*代表0个preceding element 27 dp[i][j] = dp[i][j-2]; 28 } 29 } 30 } 31 } 32 return dp[m][n]; 33 } 34 }