Skip to content

Commit 8460596

Browse files
committed
feat: add 044
1 parent a457935 commit 8460596

File tree

3 files changed

+166
-1
lines changed

3 files changed

+166
-1
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@
7373
|#|Title|Tag|
7474
|:------------- |:------------- |:------------- |
7575
|4|[Median of Two Sorted Arrays][004]|Array, Binary Search, Divide and Conquer|
76-
|10|[Regular Expression Matching][010]|String, Dynamic Programmin, Backtracking|
76+
|10|[Regular Expression Matching][010]|String, Dynamic Programming, Backtracking|
7777
|23|[Merge k Sorted Lists][023]|Linked List, Divide and Conquer, Heap|
7878
|25|[Reverse Nodes in k-Group][025]|Linked List|
79+
|44|[Reverse Nodes in k-Group][044]|String, Dynamic Programming, Backtracking, Greedy|
7980

8081

8182

@@ -132,3 +133,4 @@
132133
[010]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/010/README.md
133134
[023]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/023/README.md
134135
[025]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/025/README.md
136+
[044]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/044/README.md

note/044/README.md

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# [Wildcard Matching][title]
2+
3+
## Description
4+
5+
Implement wildcard pattern matching with support for `'?'` and `'*'`.
6+
7+
```
8+
'?' Matches any single character.
9+
'*' Matches any sequence of characters (including the empty sequence).
10+
11+
The matching should cover the entire input string (not partial).
12+
13+
The function prototype should be:
14+
bool isMatch(const char *s, const char *p)
15+
16+
Some examples:
17+
isMatch("aa","a") → false
18+
isMatch("aa","aa") → true
19+
isMatch("aaa","aa") → false
20+
isMatch("aa", "*") → true
21+
isMatch("aa", "a*") → true
22+
isMatch("ab", "?*") → true
23+
isMatch("aab", "c*a*b") → false
24+
```
25+
26+
**Tags:** String, Dynamic Programming, Backtracking, Greedy
27+
28+
29+
## 思路0
30+
31+
题意是让让你从判断`s`字符串是否通配符匹配于`p`,这道题和[Regular Expression Matching][010]很是相似,区别在于`*`,正则匹配的`*`不能单独存在,前面必须具有一个字符,其意义是表明前面的这个字符个数可以是任意个数,包括0个;而通配符的`*`是可以随意出现的,跟前面字符没有任何关系,其作用是可以表示任意字符串。在此我们可以利用*贪心算法*来解决这个问题,需要两个额外指针`p``match`来分别记录最后一个`*`的位置和`*`匹配到`s`字符串的位置,其贪心体现在如果遇到`*`,那就尽可能取匹配后方的内容,如果匹配失败,那就回到上一个遇到`*`的位置来继续贪心。
32+
33+
```java
34+
class Solution {
35+
public boolean isMatch(String s, String p) {
36+
if (p.length() == 0) return s.length() == 0;
37+
int si = 0, pi = 0, match = 0, star = -1;
38+
int sl = s.length(), pl = p.length();
39+
char[] sc = s.toCharArray(), pc = p.toCharArray();
40+
while (si < sl) {
41+
if (pi < pl && (pc[pi] == sc[si] || pc[pi] == '?')) {
42+
si++;
43+
pi++;
44+
} else if (pi < pl && pc[pi] == '*') {
45+
star = pi++;
46+
match = si;
47+
} else if (star != -1) {
48+
si = ++match;
49+
pi = star + 1;
50+
} else return false;
51+
}
52+
while (pi < pl && pc[pi] == '*') pi++;
53+
return pi == pl;
54+
}
55+
}
56+
```
57+
58+
59+
## 思路1
60+
61+
另一种思路就是动态规划了,我们定义`dp[i][j]`的真假来表示`s[0..i)`是否匹配`p[0..j)`,其状态转移方程如下所示:
62+
* 如果`p[j - 1] != '*'``P[i][j] = P[i - 1][j - 1] && (s[i - 1] == p[j - 1] || p[j - 1] == '?');`
63+
* 如果`p[j - 1] == '*'``P[i][j] = P[i][j - 1] || P[i - 1][j]`
64+
65+
```java
66+
class Solution {
67+
public boolean isMatch(String s, String p) {
68+
if (p.length() == 0) return s.length() == 0;
69+
int sl = s.length(), pl = p.length();
70+
boolean[][] dp = new boolean[sl + 1][pl + 1];
71+
char[] sc = s.toCharArray(), pc = p.toCharArray();
72+
dp[0][0] = true;
73+
for (int i = 1; i <= pl; ++i) {
74+
if (pc[i - 1] == '*') dp[0][i] = dp[0][i - 1];
75+
}
76+
for (int i = 1; i <= sl; ++i) {
77+
for (int j = 1; j <= pl; ++j) {
78+
if (pc[j - 1] != '*') {
79+
dp[i][j] = dp[i - 1][j - 1] && (sc[i - 1] == pc[j - 1] || pc[j - 1] == '?');
80+
} else {
81+
dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
82+
}
83+
}
84+
}
85+
return dp[sl][pl];
86+
}
87+
}
88+
```
89+
90+
91+
## 结语
92+
93+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我GitHub上的LeetCode题解:[awesome-java-leetcode][ajl]
94+
95+
96+
97+
[010]: https://github.com/Blankj/awesome-java-leetcode/blob/master/note/010/README.md
98+
[title]: https://leetcode.com/problems/wildcard-matching
99+
[ajl]: https://github.com/Blankj/awesome-java-leetcode
+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.blankj.hard._044;
2+
3+
/**
4+
* <pre>
5+
* author: Blankj
6+
* blog : http://blankj.com
7+
* time : 2017/10/16
8+
* desc :
9+
* </pre>
10+
*/
11+
public class Solution {
12+
// public boolean isMatch(String s, String p) {
13+
// if (p.length() == 0) return s.length() == 0;
14+
// int si = 0, pi = 0, match = 0, star = -1;
15+
// int sl = s.length(), pl = p.length();
16+
// char[] sc = s.toCharArray(), pc = p.toCharArray();
17+
// while (si < sl) {
18+
// if (pi < pl && (pc[pi] == sc[si] || pc[pi] == '?')) {
19+
// si++;
20+
// pi++;
21+
// } else if (pi < pl && pc[pi] == '*') {
22+
// star = pi++;
23+
// match = si;
24+
// } else if (star != -1) {
25+
// si = ++match;
26+
// pi = star + 1;
27+
// } else return false;
28+
// }
29+
// while (pi < pl && pc[pi] == '*') pi++;
30+
// return pi == pl;
31+
// }
32+
33+
public boolean isMatch(String s, String p) {
34+
if (p.length() == 0) return s.length() == 0;
35+
int sl = s.length(), pl = p.length();
36+
boolean[][] dp = new boolean[sl + 1][pl + 1];
37+
char[] sc = s.toCharArray(), pc = p.toCharArray();
38+
dp[0][0] = true;
39+
for (int i = 1; i <= pl; ++i) {
40+
if (pc[i - 1] == '*') dp[0][i] = dp[0][i - 1];
41+
}
42+
for (int i = 1; i <= sl; ++i) {
43+
for (int j = 1; j <= pl; ++j) {
44+
if (pc[j - 1] != '*') {
45+
dp[i][j] = dp[i - 1][j - 1] && (sc[i - 1] == pc[j - 1] || pc[j - 1] == '?');
46+
} else {
47+
dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
48+
}
49+
}
50+
}
51+
return dp[sl][pl];
52+
}
53+
54+
public static void main(String[] args) {
55+
Solution solution = new Solution();
56+
System.out.println(solution.isMatch("aa", "a")); // false
57+
System.out.println(solution.isMatch("aa", "aa")); // true
58+
System.out.println(solution.isMatch("aaa", "aa")); // false
59+
System.out.println(solution.isMatch("aa", "*")); // true
60+
System.out.println(solution.isMatch("aa", "a*")); // true
61+
System.out.println(solution.isMatch("ab", "?*")); // true
62+
System.out.println(solution.isMatch("aab", "c*a*b"));// false
63+
}
64+
}

0 commit comments

Comments
 (0)