Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 321420b

Browse files
authored
Improved task 3213
1 parent 9182a52 commit 321420b

File tree

1 file changed

+140
-37
lines changed
  • src/main/java/g3201_3300/s3213_construct_string_with_minimum_cost

1 file changed

+140
-37
lines changed
Lines changed: 140 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,165 @@
11
package g3201_3300.s3213_construct_string_with_minimum_cost;
22

33
// #Hard #Array #String #Dynamic_Programming #Suffix_Array
4-
// #2024_07_09_Time_182_ms_(100.00%)_Space_61.4_MB_(72.97%)
4+
// #2024_07_13_Time_1907_ms_(5.01%)_Space_100.9_MB_(5.09%)
55

6+
import java.util.ArrayList;
67
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.HashMap;
10+
import java.util.List;
11+
import java.util.Map;
712

813
public class Solution {
9-
private static int invalid = Integer.MAX_VALUE;
10-
11-
private static class Node {
12-
int cost = -1;
13-
Node[] chd = new Node[26];
14+
List<Integer> buildKmpPrefix(String target) {
15+
List<Integer> w = new ArrayList<>(Collections.nCopies(target.length(), 0));
16+
int k = 0;
17+
int i = 1;
18+
while (i < target.length()) {
19+
if (target.charAt(i) == target.charAt(k)) {
20+
k++;
21+
w.set(i, k);
22+
i++;
23+
} else {
24+
if (k != 0) {
25+
k = w.get(k - 1);
26+
} else {
27+
i++;
28+
}
29+
}
30+
}
31+
return w;
1432
}
1533

16-
private Node rt;
34+
List<List<Integer>> find(List<Integer> prefix, String target, String w) {
35+
List<List<Integer>> result = new ArrayList<>();
36+
int m = target.length();
37+
int n = w.length();
38+
int i = 0;
39+
int k = 0;
40+
while (i < m) {
41+
if (target.charAt(i) == w.charAt(k)) {
42+
i++;
43+
k++;
44+
}
45+
if (k == n) {
46+
result.add(Arrays.asList(i - k, i));
47+
k = prefix.get(k - 1);
48+
} else if (i < m && target.charAt(i) != w.charAt(k)) {
49+
if (k != 0) {
50+
k = prefix.get(k - 1);
51+
} else {
52+
i++;
53+
}
54+
}
55+
}
56+
return result;
57+
}
1758

1859
public int minimumCost(String target, String[] words, int[] costs) {
19-
rt = new Node();
20-
int m = words.length;
21-
int n = target.length();
22-
for (int i = 0; i < m; ++i) {
23-
if (words[i].length() <= n) {
24-
insert(words[i], costs[i]);
60+
List<Integer> targetPrefix = buildKmpPrefix(target);
61+
Node root = new Node();
62+
for (int j = 0; j < words.length; j++) {
63+
String x = words[j];
64+
if (x.length() < 320) {
65+
Node p = root;
66+
for (int i = 0; i < x.length(); i++) {
67+
char c = x.charAt(i);
68+
p.children.putIfAbsent(c, new Node());
69+
p = p.children.get(c);
70+
if (i == x.length() - 1) {
71+
if (p.cost == null) {
72+
p.cost = costs[j];
73+
} else {
74+
p.cost = Math.min(costs[j], p.cost);
75+
}
76+
}
77+
}
2578
}
2679
}
27-
int[] dp = new int[n + 1];
28-
Arrays.fill(dp, invalid);
80+
Map<Integer, Map<Integer, Integer>> dm =
81+
getIntegerMapMap(target, words, costs, targetPrefix);
82+
List<NodeCostPair> d = new ArrayList<>();
83+
d.add(new NodeCostPair(root, 0));
84+
int[] dp = new int[target.length() + 1];
85+
Arrays.fill(dp, -1);
2986
dp[0] = 0;
30-
for (int i = 0; i < n; ++i) {
31-
if (dp[i] == invalid) {
32-
continue;
33-
}
34-
int nowC = dp[i];
35-
Node now = rt;
36-
for (int j = i; now != null && j < n; ++j) {
37-
int ch = target.charAt(j) - 'a';
38-
now = now.chd[ch];
39-
if (now != null && now.cost != -1) {
40-
dp[j + 1] = Math.min(dp[j + 1], nowC + now.cost);
87+
for (int i = 0; i < target.length(); i++) {
88+
char x = target.charAt(i);
89+
List<NodeCostPair> q = new ArrayList<>();
90+
Integer t = null;
91+
for (NodeCostPair pair : d) {
92+
Node p = pair.node;
93+
int cost = pair.cost;
94+
if (p.children.containsKey(x)) {
95+
Node w = p.children.get(x);
96+
if (w.cost != null) {
97+
t = t == null ? cost + w.cost : Math.min(t, cost + w.cost);
98+
}
99+
q.add(new NodeCostPair(w, cost));
41100
}
42101
}
102+
t = getInteger(dm, i, dp, t);
103+
if (t != null) {
104+
dp[i + 1] = t;
105+
q.add(new NodeCostPair(root, t));
106+
}
107+
d = q;
43108
}
109+
return dp[target.length()];
110+
}
44111

45-
return dp[n] == invalid ? -1 : dp[n];
112+
private Integer getInteger(Map<Integer, Map<Integer, Integer>> dm, int i, int[] dp, Integer t) {
113+
Map<Integer, Integer> qm = dm.getOrDefault(i + 1, Collections.emptyMap());
114+
for (Map.Entry<Integer, Integer> entry : qm.entrySet()) {
115+
int b = entry.getKey();
116+
if (dp[b] >= 0) {
117+
t = t == null ? dp[b] + entry.getValue() : Math.min(t, dp[b] + entry.getValue());
118+
}
119+
}
120+
return t;
46121
}
47122

48-
private void insert(String wd, int cst) {
49-
int len = wd.length();
50-
Node now = rt;
51-
for (int i = 0; i < len; ++i) {
52-
int ch = wd.charAt(i) - 'a';
53-
if (now.chd[ch] == null) {
54-
now.chd[ch] = new Node();
123+
private Map<Integer, Map<Integer, Integer>> getIntegerMapMap(
124+
String target, String[] words, int[] costs, List<Integer> targetPrefix) {
125+
Map<Integer, Map<Integer, Integer>> dm = new HashMap<>();
126+
for (int i = 0; i < words.length; i++) {
127+
String word = words[i];
128+
if (word.length() >= 320) {
129+
List<List<Integer>> q = find(targetPrefix, target, word);
130+
for (List<Integer> pair : q) {
131+
int b = pair.get(0);
132+
int e = pair.get(1);
133+
dm.putIfAbsent(e, new HashMap<>());
134+
Map<Integer, Integer> qm = dm.get(e);
135+
if (qm.containsKey(b)) {
136+
qm.put(b, Math.min(qm.get(b), costs[i]));
137+
} else {
138+
qm.put(b, costs[i]);
139+
}
140+
}
55141
}
56-
now = now.chd[ch];
57142
}
58-
if (now.cost == -1 || now.cost > cst) {
59-
now.cost = cst;
143+
return dm;
144+
}
145+
146+
private static class Node {
147+
Map<Character, Node> children;
148+
Integer cost;
149+
150+
public Node() {
151+
this.children = new HashMap<>();
152+
this.cost = null;
153+
}
154+
}
155+
156+
private static class NodeCostPair {
157+
Node node;
158+
int cost;
159+
160+
public NodeCostPair(Node node, int cost) {
161+
this.node = node;
162+
this.cost = cost;
60163
}
61164
}
62165
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /