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 cc10173

Browse files
feat: add solutions to lc problem: No.3093 (doocs#2497)
No.3093.Longest Common Suffix Queries
1 parent 5f579e6 commit cc10173

File tree

7 files changed

+724
-75
lines changed

7 files changed

+724
-75
lines changed

‎solution/3000-3099/3093.Longest Common Suffix Queries/README.md‎

Lines changed: 247 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -68,71 +68,292 @@
6868

6969
## 解法
7070

71-
### 方法一
71+
### 方法一:字典树
72+
73+
题目需要我们找到最长公共后缀,我们可以考虑使用字典树。
74+
75+
我们定义字典树的节点结构如下:
76+
77+
- `children`:一个长度为 26 的数组,用于存储子节点。
78+
- `length`:当前节点的最短字符串长度。
79+
- `idx`:当前节点的字符串下标。
80+
81+
我们遍历字符串数组 `wordsContainer`,将每个字符串倒序插入字典树中。在插入的过程中,我们更新每个节点的 `length``idx`
82+
83+
接下来,我们遍历字符串数组 `wordsQuery`,对于每个字符串,我们从字典树中查找最长公共后缀的字符串下标,在寻找的过程中,如果遇到空节点,说明往后没有公共后缀了,我们可以直接返回当前节点的 `idx`
84+
85+
时间复杂度 $(L_1 \times |\Sigma| + L_2),ドル空间复杂度 $O(L_1 \times |\Sigma|),ドル其中 $L_1$ 和 $L_2$ 分别是 `wordsContainer``wordsQuery` 的字符串长度之和;而 $\Sigma$ 是字符集大小,本题中 $\Sigma = 26$。
7286

7387
<!-- tabs:start -->
7488

7589
```python
7690
class Trie:
7791
__slots__ = ("children", "length", "idx")
7892

79-
def __init__(self, length=inf, idx=inf):
93+
def __init__(self):
8094
self.children = [None] * 26
81-
self.length = length
82-
self.idx = idx
95+
self.length = inf
96+
self.idx = inf
8397

8498
def insert(self, w: str, i: int):
8599
node = self
86-
for c in w:
100+
if node.length > len(w):
101+
node.length = len(w)
102+
node.idx = i
103+
for c in w[::-1]:
87104
idx = ord(c) - ord("a")
88-
if notnode.children[idx]:
105+
if node.children[idx]isNone:
89106
node.children[idx] = Trie()
90107
node = node.children[idx]
91108
if node.length > len(w):
92109
node.length = len(w)
93110
node.idx = i
94-
elif node.length == len(w):
95-
node.idx = min(node.idx, i)
96111

97-
def query(self, w: str):
112+
def query(self, w: str) -> int:
98113
node = self
99-
ans = node.idx
100-
for c in w:
114+
for c in w[::-1]:
101115
idx = ord(c) - ord("a")
102-
if notnode.children[idx]:
116+
if node.children[idx]isNone:
103117
break
104118
node = node.children[idx]
105-
ans = node.idx
106-
return ans
119+
return node.idx
107120

108121

109122
class Solution:
110123
def stringIndices(
111124
self, wordsContainer: List[str], wordsQuery: List[str]
112125
) -> List[int]:
113-
k = 0
114-
for i, w in enumerate(wordsContainer):
115-
if len(w) < len(wordsContainer[k]):
116-
k = i
117-
trie = Trie(len(wordsContainer[k]), k)
126+
trie = Trie()
118127
for i, w in enumerate(wordsContainer):
119-
trie.insert(w[::-1], i)
120-
ans = []
121-
for i, w in enumerate(wordsQuery):
122-
ans.append(trie.query(w[::-1]))
123-
return ans
128+
trie.insert(w, i)
129+
return [trie.query(w) for w in wordsQuery]
124130
```
125131

126132
```java
127-
133+
class Trie {
134+
private final int inf = 1 << 30;
135+
private Trie[] children = new Trie[26];
136+
private int length = inf;
137+
private int idx = inf;
138+
139+
public void insert(String w, int i) {
140+
Trie node = this;
141+
if (node.length > w.length()) {
142+
node.length = w.length();
143+
node.idx = i;
144+
}
145+
for (int k = w.length() - 1; k >= 0; --k) {
146+
int idx = w.charAt(k) - 'a';
147+
if (node.children[idx] == null) {
148+
node.children[idx] = new Trie();
149+
}
150+
node = node.children[idx];
151+
if (node.length > w.length()) {
152+
node.length = w.length();
153+
node.idx = i;
154+
}
155+
}
156+
}
157+
158+
public int query(String w) {
159+
Trie node = this;
160+
for (int k = w.length() - 1; k >= 0; --k) {
161+
int idx = w.charAt(k) - 'a';
162+
if (node.children[idx] == null) {
163+
break;
164+
}
165+
node = node.children[idx];
166+
}
167+
return node.idx;
168+
}
169+
}
170+
171+
class Solution {
172+
public int[] stringIndices(String[] wordsContainer, String[] wordsQuery) {
173+
Trie trie = new Trie();
174+
for (int i = 0; i < wordsContainer.length; ++i) {
175+
trie.insert(wordsContainer[i], i);
176+
}
177+
int n = wordsQuery.length;
178+
int[] ans = new int[n];
179+
for (int i = 0; i < n; ++i) {
180+
ans[i] = trie.query(wordsQuery[i]);
181+
}
182+
return ans;
183+
}
184+
}
128185
```
129186

130187
```cpp
131-
188+
class Trie {
189+
private:
190+
const int inf = 1 << 30;
191+
Trie* children[26];
192+
int length = inf;
193+
int idx = inf;
194+
195+
public:
196+
Trie() {
197+
for (int i = 0; i < 26; ++i) {
198+
children[i] = nullptr;
199+
}
200+
}
201+
202+
void insert(string w, int i) {
203+
Trie* node = this;
204+
if (node->length > w.length()) {
205+
node->length = w.length();
206+
node->idx = i;
207+
}
208+
for (int k = w.length() - 1; k >= 0; --k) {
209+
int idx = w[k] - 'a';
210+
if (node->children[idx] == nullptr) {
211+
node->children[idx] = new Trie();
212+
}
213+
node = node->children[idx];
214+
if (node->length > w.length()) {
215+
node->length = w.length();
216+
node->idx = i;
217+
}
218+
}
219+
}
220+
221+
int query(string w) {
222+
Trie* node = this;
223+
for (int k = w.length() - 1; k >= 0; --k) {
224+
int idx = w[k] - 'a';
225+
if (node->children[idx] == nullptr) {
226+
break;
227+
}
228+
node = node->children[idx];
229+
}
230+
return node->idx;
231+
}
232+
};
233+
234+
class Solution {
235+
public:
236+
vector<int> stringIndices(vector<string>& wordsContainer, vector<string>& wordsQuery) {
237+
Trie* trie = new Trie();
238+
for (int i = 0; i < wordsContainer.size(); ++i) {
239+
trie->insert(wordsContainer[i], i);
240+
}
241+
int n = wordsQuery.size();
242+
vector<int> ans(n);
243+
for (int i = 0; i < n; ++i) {
244+
ans[i] = trie->query(wordsQuery[i]);
245+
}
246+
return ans;
247+
}
248+
};
132249
```
133250
134251
```go
252+
const inf = 1 << 30
253+
254+
type Trie struct {
255+
children [26]*Trie
256+
length int
257+
idx int
258+
}
259+
260+
func newTrie() *Trie {
261+
return &Trie{length: inf, idx: inf}
262+
}
263+
264+
func (t *Trie) insert(w string, i int) {
265+
node := t
266+
if node.length > len(w) {
267+
node.length = len(w)
268+
node.idx = i
269+
}
270+
for k := len(w) - 1; k >= 0; k-- {
271+
idx := int(w[k] - 'a')
272+
if node.children[idx] == nil {
273+
node.children[idx] = newTrie()
274+
}
275+
node = node.children[idx]
276+
if node.length > len(w) {
277+
node.length = len(w)
278+
node.idx = i
279+
}
280+
}
281+
}
282+
283+
func (t *Trie) query(w string) int {
284+
node := t
285+
for k := len(w) - 1; k >= 0; k-- {
286+
idx := int(w[k] - 'a')
287+
if node.children[idx] == nil {
288+
break
289+
}
290+
node = node.children[idx]
291+
}
292+
return node.idx
293+
}
294+
295+
func stringIndices(wordsContainer []string, wordsQuery []string) (ans []int) {
296+
trie := newTrie()
297+
for i, w := range wordsContainer {
298+
trie.insert(w, i)
299+
}
300+
for _, w := range wordsQuery {
301+
ans = append(ans, trie.query(w))
302+
}
303+
return
304+
}
305+
```
135306

307+
```ts
308+
class Trie {
309+
private children: Trie[] = new Array<Trie>(26);
310+
private length: number = Infinity;
311+
private idx: number = Infinity;
312+
313+
public insert(w: string, i: number): void {
314+
let node: Trie = this;
315+
if (node.length > w.length) {
316+
node.length = w.length;
317+
node.idx = i;
318+
}
319+
for (let k: number = w.length - 1; k >= 0; --k) {
320+
let idx: number = w.charCodeAt(k) - 'a'.charCodeAt(0);
321+
if (node.children[idx] == null) {
322+
node.children[idx] = new Trie();
323+
}
324+
node = node.children[idx];
325+
if (node.length > w.length) {
326+
node.length = w.length;
327+
node.idx = i;
328+
}
329+
}
330+
}
331+
332+
public query(w: string): number {
333+
let node: Trie = this;
334+
for (let k: number = w.length - 1; k >= 0; --k) {
335+
let idx: number = w.charCodeAt(k) - 'a'.charCodeAt(0);
336+
if (node.children[idx] == null) {
337+
break;
338+
}
339+
node = node.children[idx];
340+
}
341+
return node.idx;
342+
}
343+
}
344+
345+
function stringIndices(wordsContainer: string[], wordsQuery: string[]): number[] {
346+
const trie: Trie = new Trie();
347+
for (let i: number = 0; i < wordsContainer.length; ++i) {
348+
trie.insert(wordsContainer[i], i);
349+
}
350+
const n: number = wordsQuery.length;
351+
const ans: number[] = new Array<number>(n);
352+
for (let i: number = 0; i < n; ++i) {
353+
ans[i] = trie.query(wordsQuery[i]);
354+
}
355+
return ans;
356+
}
136357
```
137358

138359
<!-- tabs:end -->

0 commit comments

Comments
(0)

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