Skip to content

Commit ccdbf29

Browse files
authored
Add Java and C++ solutions for problem 3485.
1 parent 224bc16 commit ccdbf29

File tree

4 files changed

+599
-2
lines changed

4 files changed

+599
-2
lines changed

solution/3400-3499/3485.Longest Common Prefix of K Strings After Removal/README.md

Lines changed: 235 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,13 +114,246 @@ tags:
114114
#### Java
115115

116116
```java
117-
117+
class Solution {
118+
static class TrieNode {
119+
int count = 0;
120+
int depth = 0;
121+
int[] children = new int[26];
122+
123+
TrieNode() {
124+
for (int i = 0; i < 26; ++i) children[i] = -1;
125+
}
126+
}
127+
128+
static class SegmentTree {
129+
int n;
130+
int[] tree;
131+
int[] globalCount;
132+
133+
SegmentTree(int n, int[] globalCount) {
134+
this.n = n;
135+
this.globalCount = globalCount;
136+
this.tree = new int[4 * (n + 1)];
137+
for (int i = 0; i < tree.length; i++) tree[i] = -1;
138+
build(1, 1, n);
139+
}
140+
141+
void build(int idx, int l, int r) {
142+
if (l == r) {
143+
tree[idx] = globalCount[l] > 0 ? l : -1;
144+
return;
145+
}
146+
int mid = (l + r) / 2;
147+
build(idx * 2, l, mid);
148+
build(idx * 2 + 1, mid + 1, r);
149+
tree[idx] = Math.max(tree[idx * 2], tree[idx * 2 + 1]);
150+
}
151+
152+
void update(int idx, int l, int r, int pos, int newVal) {
153+
if (l == r) {
154+
tree[idx] = newVal > 0 ? l : -1;
155+
return;
156+
}
157+
int mid = (l + r) / 2;
158+
if (pos <= mid) {
159+
update(idx * 2, l, mid, pos, newVal);
160+
} else {
161+
update(idx * 2 + 1, mid + 1, r, pos, newVal);
162+
}
163+
tree[idx] = Math.max(tree[idx * 2], tree[idx * 2 + 1]);
164+
}
165+
166+
int query() {
167+
return tree[1];
168+
}
169+
}
170+
171+
public int[] longestCommonPrefix(String[] words, int k) {
172+
int n = words.length;
173+
int[] ans = new int[n];
174+
if (n - 1 < k) return ans;
175+
176+
ArrayList<TrieNode> trie = new ArrayList<>();
177+
trie.add(new TrieNode());
178+
179+
for (String word : words) {
180+
int cur = 0;
181+
for (char c : word.toCharArray()) {
182+
int idx = c - 'a';
183+
if (trie.get(cur).children[idx] == -1) {
184+
trie.get(cur).children[idx] = trie.size();
185+
TrieNode node = new TrieNode();
186+
node.depth = trie.get(cur).depth + 1;
187+
trie.add(node);
188+
}
189+
cur = trie.get(cur).children[idx];
190+
trie.get(cur).count++;
191+
}
192+
}
193+
194+
int maxDepth = 0;
195+
for (int i = 1; i < trie.size(); ++i) {
196+
if (trie.get(i).count >= k) {
197+
maxDepth = Math.max(maxDepth, trie.get(i).depth);
198+
}
199+
}
200+
201+
int[] globalCount = new int[maxDepth + 1];
202+
for (int i = 1; i < trie.size(); ++i) {
203+
TrieNode node = trie.get(i);
204+
if (node.count >= k && node.depth <= maxDepth) {
205+
globalCount[node.depth]++;
206+
}
207+
}
208+
209+
List<List<Integer>> fragileList = new ArrayList<>();
210+
for (int i = 0; i < n; ++i) {
211+
fragileList.add(new ArrayList<>());
212+
}
213+
214+
for (int i = 0; i < n; ++i) {
215+
int cur = 0;
216+
for (char c : words[i].toCharArray()) {
217+
int idx = c - 'a';
218+
cur = trie.get(cur).children[idx];
219+
if (trie.get(cur).count == k) {
220+
fragileList.get(i).add(trie.get(cur).depth);
221+
}
222+
}
223+
}
224+
225+
int segSize = maxDepth;
226+
if (segSize >= 1) {
227+
SegmentTree segTree = new SegmentTree(segSize, globalCount);
228+
for (int i = 0; i < n; ++i) {
229+
if (n - 1 < k) {
230+
ans[i] = 0;
231+
} else {
232+
for (int d : fragileList.get(i)) {
233+
segTree.update(1, 1, segSize, d, globalCount[d] - 1);
234+
}
235+
int res = segTree.query();
236+
ans[i] = res == -1 ? 0 : res;
237+
for (int d : fragileList.get(i)) {
238+
segTree.update(1, 1, segSize, d, globalCount[d]);
239+
}
240+
}
241+
}
242+
}
243+
244+
return ans;
245+
}
246+
}
118247
```
119248

120249
#### C++
121250

122251
```cpp
123-
252+
class Solution {
253+
public:
254+
struct TrieNode {
255+
int count = 0;
256+
int depth = 0;
257+
int children[26] = {0};
258+
};
259+
260+
class SegmentTree {
261+
public:
262+
int n;
263+
vector<int> tree;
264+
vector<int>& globalCount;
265+
SegmentTree(int n, vector<int>& globalCount) : n(n), globalCount(globalCount) {
266+
tree.assign(4 * (n + 1), -1);
267+
build(1, 1, n);
268+
}
269+
void build(int idx, int l, int r) {
270+
if (l == r) {
271+
tree[idx] = globalCount[l] > 0 ? l : -1;
272+
return;
273+
}
274+
int mid = (l + r) / 2;
275+
build(idx * 2, l, mid);
276+
build(idx * 2 + 1, mid + 1, r);
277+
tree[idx] = max(tree[idx * 2], tree[idx * 2 + 1]);
278+
}
279+
void update(int idx, int l, int r, int pos, int newVal) {
280+
if (l == r) {
281+
tree[idx] = newVal > 0 ? l : -1;
282+
return;
283+
}
284+
int mid = (l + r) / 2;
285+
if (pos <= mid)
286+
update(idx * 2, l, mid, pos, newVal);
287+
else
288+
update(idx * 2 + 1, mid + 1, r, pos, newVal);
289+
tree[idx] = max(tree[idx * 2], tree[idx * 2 + 1]);
290+
}
291+
int query() {
292+
return tree[1];
293+
}
294+
};
295+
296+
vector<int> longestCommonPrefix(vector<string>& words, int k) {
297+
int n = words.size();
298+
vector<int> ans(n, 0);
299+
if (n - 1 < k) return ans;
300+
vector<TrieNode> trie(1);
301+
for (const string& word : words) {
302+
int cur = 0;
303+
for (char c : word) {
304+
int idx = c - 'a';
305+
if (trie[cur].children[idx] == 0) {
306+
trie[cur].children[idx] = trie.size();
307+
trie.push_back({0, trie[cur].depth + 1});
308+
}
309+
cur = trie[cur].children[idx];
310+
trie[cur].count++;
311+
}
312+
}
313+
int maxDepth = 0;
314+
for (int i = 1; i < trie.size(); ++i) {
315+
if (trie[i].count >= k) {
316+
maxDepth = max(maxDepth, trie[i].depth);
317+
}
318+
}
319+
vector<int> globalCount(maxDepth + 1, 0);
320+
for (int i = 1; i < trie.size(); ++i) {
321+
if (trie[i].count >= k && trie[i].depth <= maxDepth) {
322+
globalCount[trie[i].depth]++;
323+
}
324+
}
325+
vector<vector<int>> fragileList(n);
326+
for (int i = 0; i < n; ++i) {
327+
int cur = 0;
328+
for (char c : words[i]) {
329+
int idx = c - 'a';
330+
cur = trie[cur].children[idx];
331+
if (trie[cur].count == k) {
332+
fragileList[i].push_back(trie[cur].depth);
333+
}
334+
}
335+
}
336+
int segSize = maxDepth;
337+
if (segSize >= 1) {
338+
SegmentTree segTree(segSize, globalCount);
339+
for (int i = 0; i < n; ++i) {
340+
if (n - 1 < k) {
341+
ans[i] = 0;
342+
} else {
343+
for (int d : fragileList[i]) {
344+
segTree.update(1, 1, segSize, d, globalCount[d] - 1);
345+
}
346+
int res = segTree.query();
347+
ans[i] = res == -1 ? 0 : res;
348+
for (int d : fragileList[i]) {
349+
segTree.update(1, 1, segSize, d, globalCount[d]);
350+
}
351+
}
352+
}
353+
}
354+
return ans;
355+
}
356+
};
124357
```
125358
126359
#### Go

solution/3400-3499/3485.Longest Common Prefix of K Strings After Removal/README_EN.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,136 @@ tags:
108108
#### Java
109109

110110
```java
111+
class Solution {
112+
static class TrieNode {
113+
int count = 0;
114+
int depth = 0;
115+
int[] children = new int[26];
116+
117+
TrieNode() {
118+
for (int i = 0; i < 26; ++i) children[i] = -1;
119+
}
120+
}
121+
122+
static class SegmentTree {
123+
int n;
124+
int[] tree;
125+
int[] globalCount;
126+
127+
SegmentTree(int n, int[] globalCount) {
128+
this.n = n;
129+
this.globalCount = globalCount;
130+
this.tree = new int[4 * (n + 1)];
131+
for (int i = 0; i < tree.length; i++) tree[i] = -1;
132+
build(1, 1, n);
133+
}
134+
135+
void build(int idx, int l, int r) {
136+
if (l == r) {
137+
tree[idx] = globalCount[l] > 0 ? l : -1;
138+
return;
139+
}
140+
int mid = (l + r) / 2;
141+
build(idx * 2, l, mid);
142+
build(idx * 2 + 1, mid + 1, r);
143+
tree[idx] = Math.max(tree[idx * 2], tree[idx * 2 + 1]);
144+
}
145+
146+
void update(int idx, int l, int r, int pos, int newVal) {
147+
if (l == r) {
148+
tree[idx] = newVal > 0 ? l : -1;
149+
return;
150+
}
151+
int mid = (l + r) / 2;
152+
if (pos <= mid) {
153+
update(idx * 2, l, mid, pos, newVal);
154+
} else {
155+
update(idx * 2 + 1, mid + 1, r, pos, newVal);
156+
}
157+
tree[idx] = Math.max(tree[idx * 2], tree[idx * 2 + 1]);
158+
}
159+
160+
int query() {
161+
return tree[1];
162+
}
163+
}
164+
165+
public int[] longestCommonPrefix(String[] words, int k) {
166+
int n = words.length;
167+
int[] ans = new int[n];
168+
if (n - 1 < k) return ans;
169+
170+
ArrayList<TrieNode> trie = new ArrayList<>();
171+
trie.add(new TrieNode());
172+
173+
for (String word : words) {
174+
int cur = 0;
175+
for (char c : word.toCharArray()) {
176+
int idx = c - 'a';
177+
if (trie.get(cur).children[idx] == -1) {
178+
trie.get(cur).children[idx] = trie.size();
179+
TrieNode node = new TrieNode();
180+
node.depth = trie.get(cur).depth + 1;
181+
trie.add(node);
182+
}
183+
cur = trie.get(cur).children[idx];
184+
trie.get(cur).count++;
185+
}
186+
}
111187

188+
int maxDepth = 0;
189+
for (int i = 1; i < trie.size(); ++i) {
190+
if (trie.get(i).count >= k) {
191+
maxDepth = Math.max(maxDepth, trie.get(i).depth);
192+
}
193+
}
194+
195+
int[] globalCount = new int[maxDepth + 1];
196+
for (int i = 1; i < trie.size(); ++i) {
197+
TrieNode node = trie.get(i);
198+
if (node.count >= k && node.depth <= maxDepth) {
199+
globalCount[node.depth]++;
200+
}
201+
}
202+
203+
List<List<Integer>> fragileList = new ArrayList<>();
204+
for (int i = 0; i < n; ++i) {
205+
fragileList.add(new ArrayList<>());
206+
}
207+
208+
for (int i = 0; i < n; ++i) {
209+
int cur = 0;
210+
for (char c : words[i].toCharArray()) {
211+
int idx = c - 'a';
212+
cur = trie.get(cur).children[idx];
213+
if (trie.get(cur).count == k) {
214+
fragileList.get(i).add(trie.get(cur).depth);
215+
}
216+
}
217+
}
218+
219+
int segSize = maxDepth;
220+
if (segSize >= 1) {
221+
SegmentTree segTree = new SegmentTree(segSize, globalCount);
222+
for (int i = 0; i < n; ++i) {
223+
if (n - 1 < k) {
224+
ans[i] = 0;
225+
} else {
226+
for (int d : fragileList.get(i)) {
227+
segTree.update(1, 1, segSize, d, globalCount[d] - 1);
228+
}
229+
int res = segTree.query();
230+
ans[i] = res == -1 ? 0 : res;
231+
for (int d : fragileList.get(i)) {
232+
segTree.update(1, 1, segSize, d, globalCount[d]);
233+
}
234+
}
235+
}
236+
}
237+
238+
return ans;
239+
}
240+
}
112241
```
113242

114243
#### C++

0 commit comments

Comments
 (0)