leetcode problem 10 Regular Expression Matching(动态规划)
2015-04-17 12:34
393 查看
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 有两种方法, 一种是递归直接匹配,比较好理解,代码简洁。 另一种是DP,时间复杂度小 ,为O(m*n) 其中m是匹配串长度,n是模式串长度。 先说第一种: 设S为匹配串,P为模式串,令i指向匹配串Si,令j指向模式串Pj,判断P[j+1]是否为* 如果不是*,判断S[i] == P[j] ? 如果等于,则递归处理S[i+1] P[j+1],不等于则返回false。如果P[j+1]是*,则需要综合考虑两种情况,一个是*表示前一个字符重复0次, 另一种情况是前一个字符重复 >=1次的情况,并对这两种情况取"或"。 看代码很容易理解的 Runtime: 40 ms
#define ISMATCH(a, b) (a != '\0' && (a == b || b == '.')) class Solution { public: bool isMatch(const char *s, const char *p, int i = 0, int j = 0) { if (p[j] == '\0') return s[i] == '\0'; if (p[j+1] != '*') return ISMATCH(s[i], p[j]) && isMatch(s, p, i+1, j+1); if (p[j+1] == '*') { return //0 times isMatch(s, p, i, j+2) || // more times (ISMATCH(s[i], p[j]) && isMatch(s, p, i+1, j)); } return false; } };
第二种方法用的是动态规划,非常巧妙。时间复杂度比较低为O(m*n) 令dp[i][j]表示匹配串S[1..i]是否与模式串P[1..j]匹配。 dp[i][j] = true表示匹配,dp[i][j] = false表示不匹配,状态转移方程可以写成这样: dp[i][j-2] if P[j] == '*' 考虑*表示重复前一字符为0次的情况 dp[i][j] = dp[i][j-1] if P[j] == '*' 考虑*表示重复前一字符为1次的情况(注意这里不用重复字符大于一次的情况,因为其实将来的状态矩阵中已经保存了的, 如dp[i][j]表示重复一次的情况且P[j] = '*', 那么dp[i+1][j]表示重复2次的情况, dp[i+2][j]表示重复3次的情况,一次类推.) dp[i-1][j-1] && S[i] == S[j] if P[j] != '*' 其实只要理解了dp[i][j]表示什么意思,就很好解释了。 代码如下(做了一些优化,本来状态矩阵需要DP[m] 的空间代价的,但是由于状态转移方程中在获得dp[i][j]时只用到了dp[i][j-2],所以可以只用dp[1..n]来维护状态) Runtime: 10 ms
#define ISMATCH(a, b) (a == b ||(a != '\0' && b == '.')) class Solution { public: bool isMatch(const char *s, const char *p) { int lenS = strlen(s); int lenP = strlen(p); vector<bool> dp(lenS+1, false); dp[0] = true; for (int j = 0; j < lenP; ++j) { if (j+1 < lenP && p[j+1] == '*') continue; if (p[j] == '*') { for (int i = 1; i <= lenS; ++i) { dp[i] = dp[i] || (dp[i-1] && ISMATCH(s[i-1], p[j-1])); } } else { for(int i = lenS; i > 0; --i) { dp[i] = dp[i-1] && ISMATCH(s[i-1], p[j]); } dp[0] = false; } } return dp[lenS]; } };
相关文章推荐
- LeetCode_10---Regular Expression Matching
- leetcode 10 Regular Expression Matching
- leetcode[10]Regular Expression Matching
- leetcode-10 Regular Expression Matching
- Leetcode 10 Regular Expression Matching
- [leetcode 10] Regular Expression Matching
- [leetcode] 10 Regular Expression Matching
- LeetCode - 10 - Regular Expression Matching
- [leetcode] 10 Regular Expression Matching
- LeetCoder_____Regular Expression Matching(10)
- Regular Expression Matching,regex,正则表达式匹配,利用动态规划
- [leedcode 10] Regular Expression Matching
- Leetcode Regular Expression Matching 动态规划解法
- leetcode 10 Regular Expression Matching(简单正则表达式匹配)
- leetcode-10 Regular Expression Matching
- [Leetcode] 10. Regular Expression Matching
- LeetCode 10: Regular Expression Matching
- leetcode 10: Regular Expression Matching
- leetcode 10: Regular Expression Matching 分析及解答
- LeetCode之10 --- Regular Expression Matching