Skip to content

Commit 4d6547b

Browse files
committed
Improved 3455
1 parent 49f7f02 commit 4d6547b

File tree

1 file changed

+80
-65
lines changed
  • src/main/java/g3401_3500/s3455_shortest_matching_substring

1 file changed

+80
-65
lines changed
Lines changed: 80 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,95 @@
11
package g3401_3500.s3455_shortest_matching_substring;
22

3-
// #Hard #2025_02_16_Time_976_ms_(100.00%)_Space_45.76_MB_(100.00%)
3+
// #Hard #2025_02_16_Time_91_ms_(100.00%)_Space_55.37_MB_(100.00%)
4+
5+
import java.util.ArrayList;
6+
import java.util.Arrays;
7+
import java.util.List;
48

5-
@SuppressWarnings("java:S6541")
69
public class Solution {
10+
private List<Integer> getMatch(String s, String p) {
11+
int n = s.length();
12+
int m = p.length();
13+
int[] next = new int[m];
14+
Arrays.fill(next, -1);
15+
for (int i = 1, j = -1; i < m; ++i) {
16+
while (j != -1 && p.charAt(i) != p.charAt(j + 1)) {
17+
j = next[j];
18+
}
19+
if (p.charAt(i) == p.charAt(j + 1)) {
20+
++j;
21+
}
22+
next[i] = j;
23+
}
24+
List<Integer> match = new ArrayList<>();
25+
for (int i = 0, j = -1; i < n; ++i) {
26+
while (j != -1 && s.charAt(i) != p.charAt(j + 1)) {
27+
j = next[j];
28+
}
29+
if (s.charAt(i) == p.charAt(j + 1)) {
30+
++j;
31+
}
32+
if (j == m - 1) {
33+
match.add(i - m + 1);
34+
j = next[j];
35+
}
36+
}
37+
return match;
38+
}
39+
740
public int shortestMatchingSubstring(String s, String p) {
8-
int minLen = Integer.MAX_VALUE;
9-
String[] ar = p.split("\\*");
10-
int arlen = ar.length;
11-
if (arlen == 0) {
41+
int n = s.length();
42+
int m = p.length();
43+
int[] d = {-1, -1, -1, m};
44+
for (int i = 0; i < m; ++i) {
45+
if (p.charAt(i) == '*') {
46+
d[d[1] == -1 ? 1 : 2] = i;
47+
}
48+
}
49+
List<String> subs = new ArrayList<>();
50+
for (int i = 0; i < 3; ++i) {
51+
if (d[i] + 1 < d[i + 1]) {
52+
subs.add(p.substring(d[i] + 1, d[i + 1]));
53+
}
54+
}
55+
int size = subs.size();
56+
if (size == 0) {
1257
return 0;
1358
}
14-
String temp = p.replace("*", "");
15-
if (s.contains(temp)) {
16-
return temp.length();
59+
List<List<Integer>> matches = new ArrayList<>();
60+
for (String sub : subs) {
61+
matches.add(getMatch(s, sub));
1762
}
18-
int f = s.indexOf(ar[0]);
19-
while (f != -1) {
20-
int shortLen = Integer.MAX_VALUE;
21-
if (arlen > 1) {
22-
int sec = s.indexOf(ar[1], f + ar[0].length());
23-
while (sec != -1) {
24-
if (ar[0].isEmpty()) {
25-
f = sec;
26-
}
27-
if (arlen > 2) {
28-
int third = s.indexOf(ar[2], sec + ar[1].length());
29-
if (third != -1) {
30-
if (ar[0].isEmpty() && ar[1].isEmpty()) {
31-
f = third;
32-
}
33-
shortLen = third + ar[2].length() - f;
34-
minLen = Math.min(shortLen, minLen);
35-
if (minLen == p.length() - 2) {
36-
return minLen;
37-
}
38-
if (minLen == Integer.MAX_VALUE) {
39-
return -1;
40-
}
41-
}
42-
} else {
43-
shortLen = sec + ar[1].length() - f;
44-
minLen = Math.min(shortLen, minLen);
45-
}
46-
if (minLen == p.length() - 2) {
47-
return minLen;
48-
}
49-
if (ar[1].isEmpty()) {
50-
sec = -1;
51-
} else {
52-
sec = s.indexOf(ar[1], sec + 1);
53-
}
54-
if (minLen == Integer.MAX_VALUE) {
55-
return -1;
56-
}
63+
int ans = Integer.MAX_VALUE;
64+
int[] ids = new int[size];
65+
Arrays.fill(ids, 0);
66+
while (ids[size - 1] < matches.get(size - 1).size()) {
67+
for (int i = size - 2; i >= 0; --i) {
68+
while (ids[i] + 1 < matches.get(i).size()
69+
&& matches.get(i).get(ids[i] + 1) + subs.get(i).length()
70+
<= matches.get(i + 1).get(ids[i + 1])) {
71+
++ids[i];
5772
}
58-
} else {
59-
shortLen = f + ar[0].length() - f;
60-
minLen = shortLen;
61-
}
62-
minLen = Math.min(shortLen, minLen);
63-
if (minLen == p.length() - 2) {
64-
return minLen;
6573
}
66-
if (ar[0].isEmpty()) {
67-
f = -1;
68-
} else {
69-
f = s.indexOf(ar[0], f + 1);
74+
boolean valid = true;
75+
for (int i = size - 2; i >= 0; --i) {
76+
if (ids[i] >= matches.get(i).size()
77+
|| matches.get(i).get(ids[i]) + subs.get(i).length()
78+
> matches.get(i + 1).get(ids[i + 1])) {
79+
valid = false;
80+
break;
81+
}
7082
}
71-
if (minLen == Integer.MAX_VALUE) {
72-
return -1;
83+
if (valid) {
84+
ans =
85+
Math.min(
86+
ans,
87+
matches.get(size - 1).get(ids[size - 1])
88+
+ subs.get(size - 1).length()
89+
- matches.get(0).get(ids[0]));
7390
}
91+
ids[size - 1]++;
7492
}
75-
if (minLen == Integer.MAX_VALUE) {
76-
return -1;
77-
}
78-
return minLen;
93+
return ans > n ? -1 : ans;
7994
}
8095
}

0 commit comments

Comments
 (0)