LeetCode 10 Regular Expression Matching
2016-11-03 14:59
344 查看
Implement regular expression matching with support for
思路:设定i,j作为两个游标,分别指向s[i],p[j],dp[i][j]代表s[i]和p[j]是否匹配
以及 i,j之后的字符是否已经匹配。
这里重点讲解 j + 1 < pn && p[j + 1] == '*'
的情况。因为p[j + 1] == '*' ,而'*' 可以代表0个或者多个p[j] 。
如果'*' 代表0个p[j],那么,我们就无视p[j],同时由于p[j+1]=='*',因此p[j+1]也要一起被我们无视了,因此p的游标
j 忽略p[j+1],p[j]两位,依然指向p[j+2],s的游标 i
不动,依然指向 s[i],于是我们比较
p[j+2]和s[i]是否相等即可,即dp[i][j+2]。例:我们看s= cb和 p = ca*b是否匹配,因为*可以当作0个a,所以是匹配的,这个时候当游标
j 指向p[1]='a'的时候,由于p[2]='*'因此我们就直接判断p[3]是否等于s[1]即可。
如果'*' 代表1个或者多个p[j],那么,如果s[i]
== p[j],dp[i][j]的值就依赖于dp[i+1][j],因为p[j+1]=='*',因此p[j]可以循环利用。例如s = caaaab、p
= ca*b,当游标 j
指向p[1]='a'的时候,由于p[2]='*',此时如果游标 i 指向s[4]='a'=p[1],只要dp[5][1] ==dp[5][3] =true,因此dp[4][1]也为ture;如果 i
指向s[3]=='a'=p[1],只要dp[4][1]为ture……
Runtime: 32
ms beats 61.31% of java submissions. dp解法效率上比起动辄上百毫秒的递归好很多了。
public boolean isMatch(String ss, String pp) {
int pn = pp.length(), sn = ss.length();
boolean[][] dp = new boolean[sn + 1][pn + 1];
char[] s = ss.toCharArray(), p = pp.toCharArray();
dp[sn][pn] = true;
for (int i = sn; i >= 0; i--)
for (int j = pn - 1; j >= 0; j--)
if (j + 1 < pn && p[j + 1] == '*')
dp[i][j] = dp[i][j + 2] ||
i < sn && (p[j] == '.' || s[i] == p[j]) && dp[i + 1][j];
else dp[i][j] = i < sn && (p[j] == '.' || s[i] == p[j]) && dp[i + 1][j + 1];
return dp[0][0];
}
'.'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
说明:*号之前的字符可以出现多次,比如说a*b可以和ab也可以和aab匹配,甚至也可以和b匹配,因为a可以出现0次。
思路:设定i,j作为两个游标,分别指向s[i],p[j],dp[i][j]代表s[i]和p[j]是否匹配
以及 i,j之后的字符是否已经匹配。
这里重点讲解 j + 1 < pn && p[j + 1] == '*'
的情况。因为p[j + 1] == '*' ,而'*' 可以代表0个或者多个p[j] 。
如果'*' 代表0个p[j],那么,我们就无视p[j],同时由于p[j+1]=='*',因此p[j+1]也要一起被我们无视了,因此p的游标
j 忽略p[j+1],p[j]两位,依然指向p[j+2],s的游标 i
不动,依然指向 s[i],于是我们比较
p[j+2]和s[i]是否相等即可,即dp[i][j+2]。例:我们看s= cb和 p = ca*b是否匹配,因为*可以当作0个a,所以是匹配的,这个时候当游标
j 指向p[1]='a'的时候,由于p[2]='*'因此我们就直接判断p[3]是否等于s[1]即可。
如果'*' 代表1个或者多个p[j],那么,如果s[i]
== p[j],dp[i][j]的值就依赖于dp[i+1][j],因为p[j+1]=='*',因此p[j]可以循环利用。例如s = caaaab、p
= ca*b,当游标 j
指向p[1]='a'的时候,由于p[2]='*',此时如果游标 i 指向s[4]='a'=p[1],只要dp[5][1] ==dp[5][3] =true,因此dp[4][1]也为ture;如果 i
指向s[3]=='a'=p[1],只要dp[4][1]为ture……
Runtime: 32
ms beats 61.31% of java submissions. dp解法效率上比起动辄上百毫秒的递归好很多了。
public boolean isMatch(String ss, String pp) {
int pn = pp.length(), sn = ss.length();
boolean[][] dp = new boolean[sn + 1][pn + 1];
char[] s = ss.toCharArray(), p = pp.toCharArray();
dp[sn][pn] = true;
for (int i = sn; i >= 0; i--)
for (int j = pn - 1; j >= 0; j--)
if (j + 1 < pn && p[j + 1] == '*')
dp[i][j] = dp[i][j + 2] ||
i < sn && (p[j] == '.' || s[i] == p[j]) && dp[i + 1][j];
else dp[i][j] = i < sn && (p[j] == '.' || s[i] == p[j]) && dp[i + 1][j + 1];
return dp[0][0];
}
相关文章推荐
- [leetcode] 10 Regular Expression Matching
- [Leetcode 10, Hard] 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 & 44 Wildcard 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(C)
- 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