Skip to content

Commit e8956a2

Browse files
committed
feat: add solutions to lc problem: No.0425
No.0425.Word Squares
1 parent b8b6da2 commit e8956a2

File tree

5 files changed

+535
-1
lines changed

5 files changed

+535
-1
lines changed

solution/0400-0499/0425.Word Squares/README.md

+183
Original file line numberDiff line numberDiff line change
@@ -52,22 +52,205 @@
5252

5353
<!-- 这里可写通用的实现逻辑 -->
5454

55+
**方法一:前缀树 + DFS**
56+
57+
根据已添加单词确定下一个单词的前缀,继续进行搜索。
58+
59+
比如已经添加了两个单词 $ball$ 和 $area$,要添加下一个单词,我们首先要获取下一个单词的前缀,第一个字母是第一个单词的第三个位置 $l$,第二个字母是第二个单词的第三个位置 $e$,这样就构成了前缀 $le$。然后找出所有前缀为 $le$ 的单词,作为下一个单词。
60+
5561
<!-- tabs:start -->
5662

5763
### **Python3**
5864

5965
<!-- 这里可写当前语言的特殊实现逻辑 -->
6066

6167
```python
68+
class Trie:
69+
def __init__(self):
70+
self.children = [None] * 26
71+
self.v = []
72+
73+
def insert(self, w, i):
74+
node = self
75+
for c in w:
76+
idx = ord(c) - ord('a')
77+
if node.children[idx] is None:
78+
node.children[idx] = Trie()
79+
node = node.children[idx]
80+
node.v.append(i)
81+
82+
def search(self, w):
83+
node = self
84+
for c in w:
85+
idx = ord(c) - ord('a')
86+
if node.children[idx] is None:
87+
return []
88+
node = node.children[idx]
89+
return node.v
6290

91+
92+
class Solution:
93+
def wordSquares(self, words: List[str]) -> List[List[str]]:
94+
def dfs(t):
95+
if len(t) == len(words[0]):
96+
ans.append(t[:])
97+
return
98+
idx = len(t)
99+
pref = [v[idx] for v in t]
100+
indexes = trie.search(''.join(pref))
101+
for i in indexes:
102+
t.append(words[i])
103+
dfs(t)
104+
t.pop()
105+
106+
trie = Trie()
107+
ans = []
108+
for i, w in enumerate(words):
109+
trie.insert(w, i)
110+
for w in words:
111+
dfs([w])
112+
return ans
63113
```
64114

65115
### **Java**
66116

67117
<!-- 这里可写当前语言的特殊实现逻辑 -->
68118

69119
```java
120+
class Trie {
121+
Trie[] children = new Trie[26];
122+
List<Integer> v = new ArrayList<>();
123+
124+
void insert(String word, int i) {
125+
Trie node = this;
126+
for (char c : word.toCharArray()) {
127+
c -= 'a';
128+
if (node.children[c] == null) {
129+
node.children[c] = new Trie();
130+
}
131+
node = node.children[c];
132+
node.v.add(i);
133+
}
134+
}
135+
136+
List<Integer> search(String pref) {
137+
Trie node = this;
138+
for (char c : pref.toCharArray()) {
139+
c -= 'a';
140+
if (node.children[c] == null) {
141+
return Collections.emptyList();
142+
}
143+
node = node.children[c];
144+
}
145+
return node.v;
146+
}
147+
}
148+
149+
class Solution {
150+
private Trie trie = new Trie();
151+
private String[] words;
152+
private List<List<String>> ans = new ArrayList<>();
153+
154+
public List<List<String>> wordSquares(String[] words) {
155+
this.words = words;
156+
for (int i = 0; i < words.length; ++i) {
157+
trie.insert(words[i], i);
158+
}
159+
160+
List<String> t = new ArrayList<>();
161+
for (String w : words) {
162+
t.add(w);
163+
dfs(t);
164+
t.remove(t.size() - 1);
165+
}
166+
return ans;
167+
}
168+
169+
private void dfs(List<String> t) {
170+
if (t.size() == words[0].length()) {
171+
ans.add(new ArrayList<>(t));
172+
return;
173+
}
174+
int idx = t.size();
175+
StringBuilder pref = new StringBuilder();
176+
for (String x : t) {
177+
pref.append(x.charAt(idx));
178+
}
179+
List<Integer> indexes = trie.search(pref.toString());
180+
for (int i : indexes) {
181+
t.add(words[i]);
182+
dfs(t);
183+
t.remove(t.size() - 1);
184+
}
185+
}
186+
}
187+
```
188+
189+
### **Go**
190+
191+
```go
192+
type Trie struct {
193+
children [26]*Trie
194+
v []int
195+
}
196+
197+
func newTrie() *Trie {
198+
return &Trie{}
199+
}
200+
func (this *Trie) insert(word string, i int) {
201+
node := this
202+
for _, c := range word {
203+
c -= 'a'
204+
if node.children[c] == nil {
205+
node.children[c] = newTrie()
206+
}
207+
node = node.children[c]
208+
node.v = append(node.v, i)
209+
}
210+
}
211+
func (this *Trie) search(word string) []int {
212+
node := this
213+
for _, c := range word {
214+
c -= 'a'
215+
if node.children[c] == nil {
216+
return []int{}
217+
}
218+
node = node.children[c]
219+
}
220+
return node.v
221+
}
70222

223+
func wordSquares(words []string) [][]string {
224+
trie := newTrie()
225+
for i, w := range words {
226+
trie.insert(w, i)
227+
}
228+
ans := [][]string{}
229+
var dfs func([]string)
230+
dfs = func(t []string) {
231+
if len(t) == len(words[0]) {
232+
cp := make([]string, len(t))
233+
copy(cp, t)
234+
ans = append(ans, cp)
235+
return
236+
}
237+
idx := len(t)
238+
pref := []byte{}
239+
for _, v := range t {
240+
pref = append(pref, v[idx])
241+
}
242+
indexes := trie.search(string(pref))
243+
for _, i := range indexes {
244+
t = append(t, words[i])
245+
dfs(t)
246+
t = t[:len(t)-1]
247+
}
248+
}
249+
for _, w := range words {
250+
dfs([]string{w})
251+
}
252+
return ans
253+
}
71254
```
72255

73256
### **...**

solution/0400-0499/0425.Word Squares/README_EN.md

+178-1
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,190 @@ The output consists of two word squares. The order of output does not matter (ju
4949
### **Python3**
5050

5151
```python
52-
52+
class Trie:
53+
def __init__(self):
54+
self.children = [None] * 26
55+
self.v = []
56+
57+
def insert(self, w, i):
58+
node = self
59+
for c in w:
60+
idx = ord(c) - ord('a')
61+
if node.children[idx] is None:
62+
node.children[idx] = Trie()
63+
node = node.children[idx]
64+
node.v.append(i)
65+
66+
def search(self, w):
67+
node = self
68+
for c in w:
69+
idx = ord(c) - ord('a')
70+
if node.children[idx] is None:
71+
return []
72+
node = node.children[idx]
73+
return node.v
74+
75+
76+
class Solution:
77+
def wordSquares(self, words: List[str]) -> List[List[str]]:
78+
def dfs(t):
79+
if len(t) == len(words[0]):
80+
ans.append(t[:])
81+
return
82+
idx = len(t)
83+
pref = [v[idx] for v in t]
84+
indexes = trie.search(''.join(pref))
85+
for i in indexes:
86+
t.append(words[i])
87+
dfs(t)
88+
t.pop()
89+
90+
trie = Trie()
91+
ans = []
92+
for i, w in enumerate(words):
93+
trie.insert(w, i)
94+
for w in words:
95+
dfs([w])
96+
return ans
5397
```
5498

5599
### **Java**
56100

57101
```java
102+
class Trie {
103+
Trie[] children = new Trie[26];
104+
List<Integer> v = new ArrayList<>();
105+
106+
void insert(String word, int i) {
107+
Trie node = this;
108+
for (char c : word.toCharArray()) {
109+
c -= 'a';
110+
if (node.children[c] == null) {
111+
node.children[c] = new Trie();
112+
}
113+
node = node.children[c];
114+
node.v.add(i);
115+
}
116+
}
117+
118+
List<Integer> search(String pref) {
119+
Trie node = this;
120+
for (char c : pref.toCharArray()) {
121+
c -= 'a';
122+
if (node.children[c] == null) {
123+
return Collections.emptyList();
124+
}
125+
node = node.children[c];
126+
}
127+
return node.v;
128+
}
129+
}
130+
131+
class Solution {
132+
private Trie trie = new Trie();
133+
private String[] words;
134+
private List<List<String>> ans = new ArrayList<>();
135+
136+
public List<List<String>> wordSquares(String[] words) {
137+
this.words = words;
138+
for (int i = 0; i < words.length; ++i) {
139+
trie.insert(words[i], i);
140+
}
141+
142+
List<String> t = new ArrayList<>();
143+
for (String w : words) {
144+
t.add(w);
145+
dfs(t);
146+
t.remove(t.size() - 1);
147+
}
148+
return ans;
149+
}
150+
151+
private void dfs(List<String> t) {
152+
if (t.size() == words[0].length()) {
153+
ans.add(new ArrayList<>(t));
154+
return;
155+
}
156+
int idx = t.size();
157+
StringBuilder pref = new StringBuilder();
158+
for (String x : t) {
159+
pref.append(x.charAt(idx));
160+
}
161+
List<Integer> indexes = trie.search(pref.toString());
162+
for (int i : indexes) {
163+
t.add(words[i]);
164+
dfs(t);
165+
t.remove(t.size() - 1);
166+
}
167+
}
168+
}
169+
```
58170

171+
### **Go**
172+
173+
```go
174+
type Trie struct {
175+
children [26]*Trie
176+
v []int
177+
}
178+
179+
func newTrie() *Trie {
180+
return &Trie{}
181+
}
182+
func (this *Trie) insert(word string, i int) {
183+
node := this
184+
for _, c := range word {
185+
c -= 'a'
186+
if node.children[c] == nil {
187+
node.children[c] = newTrie()
188+
}
189+
node = node.children[c]
190+
node.v = append(node.v, i)
191+
}
192+
}
193+
func (this *Trie) search(word string) []int {
194+
node := this
195+
for _, c := range word {
196+
c -= 'a'
197+
if node.children[c] == nil {
198+
return []int{}
199+
}
200+
node = node.children[c]
201+
}
202+
return node.v
203+
}
204+
205+
func wordSquares(words []string) [][]string {
206+
trie := newTrie()
207+
for i, w := range words {
208+
trie.insert(w, i)
209+
}
210+
ans := [][]string{}
211+
var dfs func([]string)
212+
dfs = func(t []string) {
213+
if len(t) == len(words[0]) {
214+
cp := make([]string, len(t))
215+
copy(cp, t)
216+
ans = append(ans, cp)
217+
return
218+
}
219+
idx := len(t)
220+
pref := []byte{}
221+
for _, v := range t {
222+
pref = append(pref, v[idx])
223+
}
224+
indexes := trie.search(string(pref))
225+
for _, i := range indexes {
226+
t = append(t, words[i])
227+
dfs(t)
228+
t = t[:len(t)-1]
229+
}
230+
}
231+
for _, w := range words {
232+
dfs([]string{w})
233+
}
234+
return ans
235+
}
59236
```
60237

61238
### **...**

0 commit comments

Comments
 (0)