Skip to content

Commit 2d950c9

Browse files
author
luzhipeng
committed
2 parents dee3118 + fb19408 commit 2d950c9

File tree

2 files changed

+141
-1
lines changed

2 files changed

+141
-1
lines changed

daily/2019-06-09.md

+134
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
## 每日一题 - Regular Expression Matching
2+
3+
### 信息卡片
4+
5+
- 时间:2019-06-09
6+
- 题目链接:https://leetcode.com/problems/regular-expression-matching/
7+
- tag:`String` `Dynamic Programming` `Backtracking`
8+
9+
### 题目描述
10+
11+
```
12+
Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.
13+
14+
15+
'.' Matches any single character.
16+
'*' Matches zero or more of the preceding element.
17+
18+
19+
The matching should cover the entire input string (not partial).
20+
21+
Note:
22+
23+
24+
s could be empty and contains only lowercase letters a-z.
25+
p could be empty and contains only lowercase letters a-z, and characters
26+
like . or *.
27+
28+
29+
Example 1:
30+
31+
32+
Input:
33+
s = "aa"
34+
p = "a"
35+
Output: false
36+
Explanation: "a" does not match the entire string "aa".
37+
38+
39+
Example 2:
40+
41+
42+
Input:
43+
s = "aa"
44+
p = "a*"
45+
Output: true
46+
Explanation: '*' means zero or more of the precedeng element, 'a'.
47+
Therefore, by repeating 'a' once, it becomes "aa".
48+
49+
50+
Example 3:
51+
52+
53+
Input:
54+
s = "ab"
55+
p = ".*"
56+
Output: true
57+
Explanation: ".*" means "zero or more (*) of any character (.)".
58+
59+
60+
Example 4:
61+
62+
63+
Input:
64+
s = "aab"
65+
p = "c*a*b"
66+
Output: true
67+
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore
68+
it matches "aab".
69+
70+
71+
Example 5:
72+
73+
74+
Input:
75+
s = "mississippi"
76+
p = "mis*is*p*."
77+
Output: false
78+
79+
```
80+
81+
本题要求判断给出的字符串和对应的正则是否匹配,匹配返回true,否则返回false。
82+
83+
本题光从解题来看,可以使用api作弊,比如用Java字符串的matches方法就可以一步过这道题,本题老老实实做的话,就需要用到动态规划。基本思路是考察s和p任意从头到两个字符之间的匹配程度,有点像编辑距离那道题。
84+
85+
### 参考答案
86+
87+
```java
88+
class Solution {
89+
public boolean isMatch(String s, String p) {
90+
if (s == null || p == null) return false;
91+
92+
// dp[i][j]代表s的前i位字符和p的前j位字符的匹配程度
93+
// dp[1][2]代表s的第一个字符和p的前两个字符的匹配
94+
// 如果s的第i个字符和p的第j个相等或者j为.那么di[i][j]的匹配程度取决于dp[i - 1][j - 1]
95+
// 如果p的第j个字符为*,那么就要考虑*匹配0个,1个,n个s的第i个字符的情况,以及根本匹配不了的情况
96+
// 根本匹配不了的意思是指p的j - 1个字符和s的第i个字符不相同,此时的匹配情况是dp[i][j] = dp[i][j - 2]
97+
// 然后是p的第j - 1个字符是.或者和s的i个字符相同的情况,此时可以匹配0 1 个n个s的第i个字符
98+
// 0个: dp[i][j] = dp[i][j - 2]
99+
// 1个: dp[i][j] = dp[i - 1][j - 1]
100+
// n个: dp[i][j] = dp[i - 1][j]
101+
// n个的最不好理解,可以按照下面的想
102+
// 我能匹配你n个,我肯定匹配了你前面的n-1个,也就是dp[i - 1][j]
103+
// 最后的结果是dp[s.length()][p.length()]
104+
boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
105+
106+
dp[0][0] = true;
107+
108+
for (int j = 2; j <= p.length(); j++) {
109+
if (p.charAt(j - 1) == '*' && dp[0][j - 2]) dp[0][j] = true;
110+
}
111+
112+
for (int i = 1; i <= s.length(); i++) {
113+
for (int j = 1; j <= p.length(); j++) {
114+
if (p.charAt(j - 1) == '.' || p.charAt(j - 1) == s.charAt(i - 1)) {
115+
dp[i][j] = dp[i - 1][j - 1];
116+
} else if (p.charAt(j - 1) == '*') {
117+
if (p.charAt(j - 2) != s.charAt(i - 1) && p.charAt(j - 2) != '.') {
118+
dp[i][j] = dp[i][j - 2];
119+
} else {
120+
dp[i][j] = (dp[i][j - 2] || dp[i][j - 1] || dp[i - 1][j]);
121+
}
122+
}
123+
}
124+
}
125+
126+
return dp[s.length()][p.length()];
127+
}
128+
}
129+
130+
```
131+
### 其他优秀解答
132+
```
133+
暂无
134+
```

daily/README.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@ tag: `Array`
2525

2626
#### [347.Top K Frequent Elements](./2019-06-08.md)
2727

28-
tag: `HashTable Heap`
28+
tag: `HashTable` `Heap`
2929

3030
时间: 2019-06-08
3131

32+
#### [10.Regular Expression Matching](./2019-06-09.md)
33+
34+
tag: `String` `Dynamic Programming` `Backtracking`
35+
36+
时间: 2019-06-09
37+
3238
#### [617. Merge Two Binary Trees](./2019-06-10.md)
3339

3440
tag: `Tree`

0 commit comments

Comments
 (0)