-
Notifications
You must be signed in to change notification settings - Fork 232
/
isMatch_2014_1228.java
executable file
·183 lines (152 loc) · 5.99 KB
/
isMatch_2014_1228.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package Algorithms.string;
public class isMatch_2014_1228 {
// Solution 2: DFS.
public boolean isMatch1(String s, String p) {
if (s == null || p == null) {
return false;
}
return dfs(s, p, 0, 0);
}
public boolean dfs(String s, String p, int indexS, int indexP) {
int lenS = s.length();
int lenP = p.length();
// THE BASE CASE:
if (indexP >= lenP) {
// indexP is out of range. Then the s should also be empty.
return indexS >= lenS;
}
// The first Case: next node is *
if (indexP != lenP - 1 && p.charAt(indexP + 1) == '*') {
// p can skip 2 node, and the S can skip 0 or more characters.
if (dfs(s, p, indexS, indexP + 2)) {
return true;
}
for (int i = indexS; i < lenS; i++) {
// the char is not equal.
// bug 2: Line 31: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
if (!isSame(s.charAt(i), p.charAt(indexP))) {
return false;
}
if (dfs(s, p, i + 1, indexP + 2)) {
return true;
}
}
// Not any of them can match.
return false;
} else {
// S should have at least one character left.
if (indexS >= lenS) {
return false;
}
if (!isSame(s.charAt(indexS), p.charAt(indexP))) {
return false;
}
// bug 1: forget ';'
return dfs(s, p, indexS + 1, indexP + 1);
}
}
public boolean isSame(char c, char p) {
return p == '.' || c == p;
}
// solution3: dfs + memory
public boolean isMatch2(String s, String p) {
if (s == null || p == null) {
return false;
}
int[][] mem = new int[s.length() + 1][p.length() + 1];
// BUG 1: forget to init the memory array.
// BUG 2: the corner is <=
for (int i = 0; i <= s.length(); i++) {
for (int j = 0; j <= p.length(); j++) {
mem[i][j] = -1;
}
}
return dfsMem(s, p, 0, 0, mem);
}
public boolean dfsMem(String s, String p, int indexS, int indexP, int[][] mem) {
int lenS = s.length();
int lenP = p.length();
if (mem[indexS][indexP] != -1) {
return mem[indexS][indexP] == 1;
}
// THE BASE CASE:
if (indexP >= lenP) {
// indexP is out of range. Then the s should also be empty.
mem[indexS][indexP] = indexS >= lenS ? 1: 0;
return indexS >= lenS;
}
// The first Case: next node is *
if (indexP != lenP - 1 && p.charAt(indexP + 1) == '*') {
// p can skip 2 node, and the S can skip 0 or more characters.
if (dfsMem(s, p, indexS, indexP + 2, mem)) {
mem[indexS][indexP] = 1;
return true;
}
for (int i = indexS; i < lenS; i++) {
// the char is not equal.
// bug 2: Line 31: java.lang.StringIndexOutOfBoundsException: String index out of range: -1
if (!isSame(s.charAt(i), p.charAt(indexP))) {
mem[indexS][indexP] = 0;
return false;
}
if (dfsMem(s, p, i + 1, indexP + 2, mem)) {
mem[indexS][indexP] = 1;
return true;
}
}
// Not any of them can match.
mem[indexS][indexP] = 0;
return false;
} else {
// S should have at least one character left.
boolean ret = indexS < lenS
&& isSame(s.charAt(indexS), p.charAt(indexP))
&& dfsMem(s, p, indexS + 1, indexP + 1, mem);
mem[indexS][indexP] = ret ? 1: 0;
return ret;
}
}
// solution4: DP
public boolean isMatch(String s, String p) {
if (s == null || p == null) {
return false;
}
// bug 2: should use boolean instead of int.
boolean[][] D = new boolean[s.length() + 1][p.length() + 1];
// D[i][j]: i, j, the length of String s and String p.
for (int i = 0; i <= s.length(); i++) {
for (int j = 0; j <= p.length(); j++) {
if (j == 0) {
// when p is empth, the s should be empty.
D[i][j] = i == 0;
} else if (p.charAt(j - 1) == '*') {
/*
P has at least one node.
*/
// The last node in p is '*'
if (j < 2) {
// a error: there should be a character before *.
//return false;
}
// we can match 0 characters or match more characters.
for (int k = 0; k <= i; k++) {
// BUG 3: severe! Forget to deal with the empty string!!
if (k != 0 && !isSame(s.charAt(i - k), p.charAt(j - 2))) {
D[i][j] = false;
break;
}
if (D[i - k][j - 2]) {
D[i][j] = true;
break;
}
}
} else {
D[i][j] = i >= 1
&& isSame(s.charAt(i - 1), p.charAt(j - 1))
&& D[i - 1][j - 1];
}
}
}
return D[s.length()][p.length()];
}
}