Skip to content

Commit d8383fa

Browse files
author
wangliang
committed
44更新
1 parent a31e436 commit d8383fa

File tree

1 file changed

+163
-1
lines changed

1 file changed

+163
-1
lines changed

leetCode-44-Wildcard-Matching.md

+163-1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,168 @@ boolean isMatch(String str, String pattern) {
125125

126126
如果非要用递归的话,可以按照动态规划那个思路,先压栈,然后出栈过程其实就是动态规划那样了。所以其实不如直接动态规划。
127127

128+
# 更新
129+
130+
`2021.7.7` 日更新。(太久没写 `java` 代码了,由于换了电脑 `eclipes` 也没有,在 `vscode` 里写 `java` 竟然不会写了,习惯了写 `js` ,分号不加,类型不管,写 `java` 有点不适应了,哈哈)
131+
132+
上边说到当时按 [第 10 题](https://leetcode.wang/leetCode-10-Regular-Expression-Matching.html) 的递归思路超时了,代码如下:
133+
134+
```java
135+
class Solution {
136+
public boolean isMatch(String text, String pattern) {
137+
if (pattern.isEmpty())
138+
return text.isEmpty();
139+
if (text.isEmpty())
140+
return pattern.isEmpty() || isStars(pattern);
141+
142+
boolean first_match = (!text.isEmpty() && (pattern.charAt(0) == text.charAt(0) || pattern.charAt(0) == '?'));
143+
if (pattern.charAt(0) == '*') {
144+
return (isMatch(text.substring(1), pattern) || (isMatch(text.substring(1), pattern.substring(1))))
145+
|| (isMatch(text, pattern.substring(1)));
146+
} else {
147+
return first_match && isMatch(text.substring(1), pattern.substring(1));
148+
}
149+
}
150+
151+
private boolean isStars(String pattern) {
152+
// TODO Auto-generated method stub
153+
for (int i = 0; i < pattern.length(); i++) {
154+
if (pattern.charAt(i) != '*') {
155+
return false;
156+
}
157+
}
158+
return true;
159+
}
160+
}
161+
```
162+
163+
代码很好理解,这里就不多说了,可以参考 [第 10 题](https://leetcode.wang/leetCode-10-Regular-Expression-Matching.html) 的分析,但有个问题就是会超时。
164+
165+
![](https://windliang.oss-cn-beijing.aliyuncs.com/leetcode44n1.jpg)
166+
167+
前几天 [@xuyuntian](https://xuyuntian.gitee.io/) 加了微信告诉我他写出了一个递归的写法,[代码](https://gitee.com/xuyuntian/leetcode/blob/master/src/_44.java) 如下:
168+
169+
```java
170+
class Solution {
171+
public boolean isMatch(String s, String p) {
172+
return dfs(new Boolean[s.length()][p.length()], s.toCharArray(), p.toCharArray(), 0, 0);
173+
}
174+
private boolean dfs(Boolean[][] dp, char[] s, char[] p, int i, int j) {
175+
if (i == s.length && j == p.length) return true;
176+
if (i > s.length || (i < s.length && j == p.length)) return false;
177+
if (i < s.length) {
178+
if (dp[i][j] != null) return dp[i][j];
179+
if (p[j] == '?' || p[j] == s[i]) {
180+
return dp[i][j] = dfs(dp, s, p, i + 1, j + 1);
181+
}
182+
}
183+
boolean res = false;
184+
if (p[j] == '*') {
185+
res = dfs(dp, s, p, i + 1, j + 1) || dfs(dp, s, p, i + 1, j) || dfs(dp, s, p, i, j + 1);
186+
}
187+
if (i < s.length) dp[i][j] = res;
188+
return res;
189+
}
190+
}
191+
```
192+
193+
看完以后突然就悟了,对啊,`memoization` 技术啊,把递归过程中的结果存起来呀!
194+
195+
于是我把自己的递归代码用 `HashMap` 改良了一版,把所有结果都用 `HashMap` 存起来。
196+
197+
```java
198+
class Solution {
199+
public boolean isMatch(String text, String pattern) {
200+
HashMap<String,Boolean> map=new HashMap<>();
201+
return isMatchHelper(text, pattern, map);
202+
}
203+
public boolean isMatchHelper(String text, String pattern, HashMap<String,Boolean> map) {
204+
if (pattern.isEmpty())
205+
return text.isEmpty();
206+
if (text.isEmpty())
207+
return pattern.isEmpty() || isStars(pattern);
208+
String key = text + '@' + pattern;
209+
if(map.containsKey(key)) {
210+
return map.get(key);
211+
}
212+
boolean first_match = (!text.isEmpty() && (pattern.charAt(0) == text.charAt(0) || pattern.charAt(0) == '?'));
213+
if (pattern.charAt(0) == '*') {
214+
boolean res = (isMatchHelper(text.substring(1), pattern, map) || (isMatchHelper(text.substring(1), pattern.substring(1), map)))
215+
|| (isMatchHelper(text, pattern.substring(1), map));
216+
map.put(key, res);
217+
return res;
218+
} else {
219+
boolean res = first_match && isMatchHelper(text.substring(1), pattern.substring(1), map);
220+
map.put(key, res);
221+
return res;
222+
}
223+
}
224+
225+
private boolean isStars(String pattern) {
226+
// TODO Auto-generated method stub
227+
for (int i = 0; i < pattern.length(); i++) {
228+
if (pattern.charAt(i) != '*') {
229+
return false;
230+
}
231+
}
232+
return true;
233+
}
234+
}
235+
```
236+
237+
遗憾的是竟然超内存了。
238+
239+
![](https://windliang.oss-cn-beijing.aliyuncs.com/leetcode44n2.jpg)
240+
241+
又看了下 [@xuyuntian](https://xuyuntian.gitee.io/) 的代码,原因只能是 `HashMap` 太占内存了,于是我也改成了用数组缓存结果。同样的,需要将下标在递归中传递。
242+
243+
```java
244+
class Solution {
245+
public boolean isMatch(String text, String pattern) {
246+
boolean res = isMatchHelper(text, 0, pattern, 0, new Boolean[text.length()][pattern.length()]);
247+
return res;
248+
}
249+
250+
public boolean isMatchHelper(String textOrigin, int textStart, String patternOrigin, int patternStart, Boolean[][] map) {
251+
String text = textOrigin.substring(textStart);
252+
String pattern = patternOrigin.substring(patternStart);
253+
if (pattern.isEmpty())
254+
return text.isEmpty();
255+
if (text.isEmpty())
256+
return pattern.isEmpty() || isStars(pattern);
257+
if(map[textStart][patternStart] != null) {
258+
return map[textStart][patternStart] ;
259+
}
260+
boolean first_match = (!text.isEmpty() && (pattern.charAt(0) == text.charAt(0) || pattern.charAt(0) == '?'));
261+
if (pattern.charAt(0) == '*') {
262+
boolean res = (isMatchHelper(textOrigin, textStart + 1,patternOrigin, patternStart, map) || (isMatchHelper(textOrigin, textStart + 1 ,patternOrigin, patternStart + 1, map)))
263+
|| (isMatchHelper(textOrigin, textStart, patternOrigin, patternStart + 1, map));
264+
map[textStart][patternStart] = res;
265+
return res;
266+
} else {
267+
boolean res = first_match && isMatchHelper(textOrigin, textStart + 1 ,patternOrigin, patternStart + 1, map);
268+
map[textStart][patternStart] = res;
269+
return res;
270+
}
271+
}
272+
273+
private boolean isStars(String pattern) {
274+
// TODO Auto-generated method stub
275+
for (int i = 0; i < pattern.length(); i++) {
276+
if (pattern.charAt(i) != '*') {
277+
return false;
278+
}
279+
}
280+
return true;
281+
}
282+
}
283+
```
284+
285+
终于 `AC` 了!
286+
287+
![](https://windliang.oss-cn-beijing.aliyuncs.com/leetcode44n3.jpg)
288+
128289
#
129290

130-
动态规划的应用,理清递推的公式就可以。另外迭代的方法,也让人眼前一亮。
291+
动态规划的应用,理清递推的公式就可以。另外迭代的方法,也让人眼前一亮。
292+

0 commit comments

Comments
 (0)