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 8f3e250

Browse files
authored
Improved task 3213
1 parent 6f21154 commit 8f3e250

File tree

3 files changed

+70
-135
lines changed

3 files changed

+70
-135
lines changed

‎build.gradle‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ plugins {
22
id 'java'
33
id 'maven-publish'
44
id 'com.diffplug.spotless' version '6.25.0'
5-
id 'org.sonarqube' version '5.0.0.4638'
5+
id 'org.sonarqube' version '5.1.0.4882'
66
id 'jacoco'
77
}
88

‎src/main/java/g3201_3300/s3203_find_minimum_diameter_after_merging_two_trees/Solution.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package g3201_3300.s3203_find_minimum_diameter_after_merging_two_trees;
22

3-
// #Hard #Tree #Graph #Depth_First_Search #Breadth_First_Search
3+
// #Hard #Depth_First_Search #Breadth_First_Search #Tree #Graph
44
// #2024_07_04_Time_29_ms_(99.83%)_Space_110.9_MB_(86.36%)
55

66
import java.util.Arrays;
Lines changed: 68 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,165 +1,100 @@
11
package g3201_3300.s3213_construct_string_with_minimum_cost;
22

33
// #Hard #Array #String #Dynamic_Programming #Suffix_Array
4-
// #2024_07_13_Time_1907_ms_(5.01%)_Space_100.9_MB_(5.09%)
4+
// #2024_07_15_Time_261_ms_(88.55%)_Space_67.2_MB_(45.91%)
55

6-
import java.util.ArrayList;
76
import java.util.Arrays;
8-
import java.util.Collections;
9-
import java.util.HashMap;
10-
import java.util.List;
11-
import java.util.Map;
127

138
public class Solution {
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-
}
9+
private static class ACAutomaton {
10+
private static class Node {
11+
private char key;
12+
private Integer val = null;
13+
private int len;
14+
private final Node[] next = new Node[26];
15+
private Node suffix = null;
16+
private Node output = null;
17+
private Node parent = null;
3018
}
31-
return w;
32-
}
3319

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++;
20+
public Node build(String[] patterns, int[] values) {
21+
Node root = new Node();
22+
root.suffix = root;
23+
root.output = root;
24+
for (int i = 0; i < patterns.length; i++) {
25+
put(root, patterns[i], values[i]);
4426
}
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);
27+
for (int i = 0; i < root.next.length; i++) {
28+
if (root.next[i] == null) {
29+
root.next[i] = root;
5130
} else {
52-
i++;
31+
root.next[i].suffix = root;
5332
}
5433
}
34+
return root;
5535
}
56-
return result;
57-
}
5836

59-
public int minimumCost(String target, String[] words, int[] costs) {
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-
}
37+
private void put(Node root, String s, int val) {
38+
Node node = root;
39+
for (char c : s.toCharArray()) {
40+
if (node.next[c - 'a'] == null) {
41+
node.next[c - 'a'] = new Node();
42+
node.next[c - 'a'].parent = node;
43+
node.next[c - 'a'].key = c;
7744
}
45+
node = node.next[c - 'a'];
7846
}
79-
}
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);
86-
dp[0] = 0;
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));
100-
}
47+
if (node.val == null || node.val > val) {
48+
node.val = val;
49+
node.len = s.length();
10150
}
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;
10851
}
109-
return dp[target.length()];
110-
}
11152

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());
53+
public Node getOutput(Node node) {
54+
if (node.output == null) {
55+
Node suffix = getSuffix(node);
56+
node.output = suffix.val != null ? suffix : getOutput(suffix);
11857
}
58+
return node.output;
11959
}
120-
return t;
121-
}
12260

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-
}
61+
private Node go(Node node, char c) {
62+
if (node.next[c - 'a'] == null) {
63+
node.next[c - 'a'] = go(getSuffix(node), c);
14164
}
65+
return node.next[c - 'a'];
14266
}
143-
return dm;
144-
}
145-
146-
private static class Node {
147-
Map<Character, Node> children;
148-
Integer cost;
14967

150-
public Node() {
151-
this.children = new HashMap<>();
152-
this.cost = null;
68+
private Node getSuffix(Node node) {
69+
if (node.suffix == null) {
70+
node.suffix = go(getSuffix(node.parent), node.key);
71+
if (node.suffix.val != null) {
72+
node.output = node.suffix;
73+
} else {
74+
node.output = node.suffix.output;
75+
}
76+
}
77+
return node.suffix;
15378
}
15479
}
15580

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;
81+
public int minimumCost(String target, String[] words, int[] costs) {
82+
ACAutomaton ac = new ACAutomaton();
83+
ACAutomaton.Node root = ac.build(words, costs);
84+
int[] dp = new int[target.length() + 1];
85+
Arrays.fill(dp, Integer.MAX_VALUE / 2);
86+
dp[0] = 0;
87+
ACAutomaton.Node node = root;
88+
for (int i = 1; i < dp.length; i++) {
89+
node = ac.go(node, target.charAt(i - 1));
90+
for (ACAutomaton.Node temp = node;
91+
temp != null && temp != root;
92+
temp = ac.getOutput(temp)) {
93+
if (temp.val != null && dp[i - temp.len] < Integer.MAX_VALUE / 2) {
94+
dp[i] = Math.min(dp[i], dp[i - temp.len] + temp.val);
95+
}
96+
}
16397
}
98+
return dp[dp.length - 1] >= Integer.MAX_VALUE / 2 ? -1 : dp[dp.length - 1];
16499
}
165100
}

0 commit comments

Comments
(0)

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