Skip to content

Commit d9caea3

Browse files
committed
feat: add solutions to lc/lcof2 problem
* lc No.0820 & lcof2 No.065.Short Encoding of Words
1 parent 91e728f commit d9caea3

File tree

3 files changed

+245
-36
lines changed

3 files changed

+245
-36
lines changed

lcof2/剑指 Offer II 065. 最短的单词编码/README.md

+139-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@ words[2] = "bell" ,s 开始于 indices[2] = 5 到下一个 '#&#3
5353

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

56-
题目大意:充分利用重叠的后缀,使有效编码尽可能短
56+
**方法一:前缀树**
57+
58+
题目大意:充分利用重叠的后缀,使有效编码尽可能短。
59+
60+
判断当前单词是否是其他单词的后缀,若是,就不用写入助记字符串中,否则需要写入并且加上一个 # 后缀。
5761

5862
<!-- tabs:start -->
5963

@@ -72,8 +76,8 @@ class Solution:
7276
root = Trie()
7377
for w in words:
7478
cur = root
75-
for i in range(len(w) - 1, -1, -1):
76-
idx = ord(w[i]) - ord('a')
79+
for c in w[::-1]:
80+
idx = ord(c) - ord("a")
7781
if cur.children[idx] == None:
7882
cur.children[idx] = Trie()
7983
cur = cur.children[idx]
@@ -90,6 +94,30 @@ class Solution:
9094
return ans
9195
```
9296

97+
```python
98+
class Trie:
99+
def __init__(self):
100+
self.children = [None] * 26
101+
102+
def insert(self, w):
103+
node = self
104+
pref = True
105+
for c in w:
106+
idx = ord(c) - ord("a")
107+
if node.children[idx] is None:
108+
node.children[idx] = Trie()
109+
pref = False
110+
node = node.children[idx]
111+
return 0 if pref else len(w) + 1
112+
113+
114+
class Solution:
115+
def minimumLengthEncoding(self, words: List[str]) -> int:
116+
words.sort(key=lambda x: -len(x))
117+
trie = Trie()
118+
return sum(trie.insert(w[::-1]) for w in words)
119+
```
120+
93121
### **Java**
94122

95123
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -132,6 +160,38 @@ class Solution {
132160
}
133161
```
134162

163+
```java
164+
class Trie {
165+
Trie[] children = new Trie[26];
166+
167+
int insert(String w) {
168+
Trie node = this;
169+
boolean pref = true;
170+
for (int i = w.length() - 1; i >= 0; --i) {
171+
int idx = w.charAt(i) - 'a';
172+
if (node.children[idx] == null) {
173+
pref = false;
174+
node.children[idx] = new Trie();
175+
}
176+
node = node.children[idx];
177+
}
178+
return pref ? 0 : w.length() + 1;
179+
}
180+
}
181+
182+
class Solution {
183+
public int minimumLengthEncoding(String[] words) {
184+
Arrays.sort(words, (a, b) -> b.length() - a.length());
185+
int ans = 0;
186+
Trie trie = new Trie();
187+
for (String w : words) {
188+
ans += trie.insert(w);
189+
}
190+
return ans;
191+
}
192+
}
193+
```
194+
135195
### **Go**
136196

137197
```go
@@ -168,6 +228,43 @@ func dfs(cur *trie, l int) int {
168228
}
169229
```
170230

231+
```go
232+
type Trie struct {
233+
children [26]*Trie
234+
}
235+
236+
func newTrie() *Trie {
237+
return &Trie{}
238+
}
239+
240+
func (this *Trie) insert(w string) int {
241+
node := this
242+
pref := true
243+
for i := len(w) - 1; i >= 0; i-- {
244+
idx := w[i] - 'a'
245+
if node.children[idx] == nil {
246+
pref = false
247+
node.children[idx] = newTrie()
248+
}
249+
node = node.children[idx]
250+
}
251+
if pref {
252+
return 0
253+
}
254+
return len(w) + 1
255+
}
256+
257+
func minimumLengthEncoding(words []string) int {
258+
sort.Slice(words, func(i, j int) bool { return len(words[i]) > len(words[j]) })
259+
trie := newTrie()
260+
ans := 0
261+
for _, w := range words {
262+
ans += trie.insert(w)
263+
}
264+
return ans
265+
}
266+
```
267+
171268
### **C++**
172269

173270
```cpp
@@ -209,6 +306,45 @@ private:
209306
};
210307
```
211308
309+
```cpp
310+
class Trie {
311+
public:
312+
vector<Trie*> children;
313+
Trie() : children(26) {}
314+
315+
int insert(string w) {
316+
Trie* node = this;
317+
bool pref = true;
318+
for (char c : w)
319+
{
320+
c -= 'a';
321+
if (!node->children[c])
322+
{
323+
pref = false;
324+
node->children[c] = new Trie();
325+
}
326+
node = node->children[c];
327+
}
328+
return pref ? 0 : w.size() + 1;
329+
}
330+
};
331+
332+
class Solution {
333+
public:
334+
int minimumLengthEncoding(vector<string>& words) {
335+
sort(words.begin(), words.end(), [](string &a, string &b) {return a.size() > b.size();});
336+
Trie* trie = new Trie();
337+
int ans = 0;
338+
for (auto& w : words)
339+
{
340+
reverse(w.begin(), w.end());
341+
ans += trie->insert(w);
342+
}
343+
return ans;
344+
}
345+
};
346+
```
347+
212348
### **...**
213349

214350
```

lcof2/剑指 Offer II 065. 最短的单词编码/Solution.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ def minimumLengthEncoding(self, words: List[str]) -> int:
88
root = Trie()
99
for w in words:
1010
cur = root
11-
for i in range(len(w) - 1, -1, -1):
12-
idx = ord(w[i]) - ord('a')
11+
for c in w[::-1]:
12+
idx = ord(c) - ord("a")
1313
if cur.children[idx] == None:
1414
cur.children[idx] = Trie()
1515
cur = cur.children[idx]

solution/0800-0899/0820.Short Encoding of Words/README.md

+104-31
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,12 @@ words[2] = "bell" ,s 开始于 indices[2] = 5 到下一个 '#' 结束的子字
5151

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

54+
**方法一:前缀树**
55+
5456
题目大意:充分利用重叠的后缀,使有效编码尽可能短。
5557

58+
判断当前单词是否是其他单词的后缀,若是,就不用写入助记字符串中,否则需要写入并且加上一个 # 后缀。
59+
5660
<!-- tabs:start -->
5761

5862
### **Python3**
@@ -70,8 +74,8 @@ class Solution:
7074
root = Trie()
7175
for w in words:
7276
cur = root
73-
for i in range(len(w) - 1, -1, -1):
74-
idx = ord(w[i]) - ord('a')
77+
for c in w[::-1]:
78+
idx = ord(c) - ord("a")
7579
if cur.children[idx] == None:
7680
cur.children[idx] = Trie()
7781
cur = cur.children[idx]
@@ -89,13 +93,27 @@ class Solution:
8993
```
9094

9195
```python
96+
class Trie:
97+
def __init__(self):
98+
self.children = [None] * 26
99+
100+
def insert(self, w):
101+
node = self
102+
pref = True
103+
for c in w:
104+
idx = ord(c) - ord("a")
105+
if node.children[idx] is None:
106+
node.children[idx] = Trie()
107+
pref = False
108+
node = node.children[idx]
109+
return 0 if pref else len(w) + 1
110+
111+
92112
class Solution:
93113
def minimumLengthEncoding(self, words: List[str]) -> int:
94-
s = set(words)
95-
for word in words:
96-
for i in range(1, len(word)):
97-
s.discard(word[i:])
98-
return sum(len(word) + 1 for word in s)
114+
words.sort(key=lambda x: -len(x))
115+
trie = Trie()
116+
return sum(trie.insert(w[::-1]) for w in words)
99117
```
100118

101119
### **Java**
@@ -141,17 +159,31 @@ class Solution {
141159
```
142160

143161
```java
144-
class Solution {
145-
public int minimumLengthEncoding(String[] words) {
146-
Set<String> s = new HashSet<>(Arrays.asList(words));
147-
for (String word : words) {
148-
for (int i = 1; i < word.length(); ++i) {
149-
s.remove(word.substring(i));
162+
class Trie {
163+
Trie[] children = new Trie[26];
164+
165+
int insert(String w) {
166+
Trie node = this;
167+
boolean pref = true;
168+
for (int i = w.length() - 1; i >= 0; --i) {
169+
int idx = w.charAt(i) - 'a';
170+
if (node.children[idx] == null) {
171+
pref = false;
172+
node.children[idx] = new Trie();
150173
}
174+
node = node.children[idx];
151175
}
176+
return pref ? 0 : w.length() + 1;
177+
}
178+
}
179+
180+
class Solution {
181+
public int minimumLengthEncoding(String[] words) {
182+
Arrays.sort(words, (a, b) -> b.length() - a.length());
152183
int ans = 0;
153-
for (String word : s) {
154-
ans += word.length() + 1;
184+
Trie trie = new Trie();
185+
for (String w : words) {
186+
ans += trie.insert(w);
155187
}
156188
return ans;
157189
}
@@ -195,19 +227,37 @@ func dfs(cur *trie, l int) int {
195227
```
196228

197229
```go
198-
func minimumLengthEncoding(words []string) int {
199-
s := make(map[string]bool)
200-
for _, word := range words {
201-
s[word] = true
202-
}
203-
for _, word := range words {
204-
for i, n := 1, len(word); i < n; i++ {
205-
delete(s, word[i:n])
230+
type Trie struct {
231+
children [26]*Trie
232+
}
233+
234+
func newTrie() *Trie {
235+
return &Trie{}
236+
}
237+
238+
func (this *Trie) insert(w string) int {
239+
node := this
240+
pref := true
241+
for i := len(w) - 1; i >= 0; i-- {
242+
idx := w[i] - 'a'
243+
if node.children[idx] == nil {
244+
pref = false
245+
node.children[idx] = newTrie()
206246
}
247+
node = node.children[idx]
207248
}
249+
if pref {
250+
return 0
251+
}
252+
return len(w) + 1
253+
}
254+
255+
func minimumLengthEncoding(words []string) int {
256+
sort.Slice(words, func(i, j int) bool { return len(words[i]) > len(words[j]) })
257+
trie := newTrie()
208258
ans := 0
209-
for word := range s {
210-
ans += len(word) + 1
259+
for _, w := range words {
260+
ans += trie.insert(w)
211261
}
212262
return ans
213263
}
@@ -255,16 +305,39 @@ private:
255305
```
256306
257307
```cpp
308+
class Trie {
309+
public:
310+
vector<Trie*> children;
311+
Trie() : children(26) {}
312+
313+
int insert(string w) {
314+
Trie* node = this;
315+
bool pref = true;
316+
for (char c : w)
317+
{
318+
c -= 'a';
319+
if (!node->children[c])
320+
{
321+
pref = false;
322+
node->children[c] = new Trie();
323+
}
324+
node = node->children[c];
325+
}
326+
return pref ? 0 : w.size() + 1;
327+
}
328+
};
329+
258330
class Solution {
259331
public:
260332
int minimumLengthEncoding(vector<string>& words) {
261-
unordered_set<string> s(words.begin(), words.end());
262-
for (auto& word : words)
263-
for (int i = 1; i < word.size(); ++i)
264-
s.erase(word.substr(i));
333+
sort(words.begin(), words.end(), [](string &a, string &b) {return a.size() > b.size();});
334+
Trie* trie = new Trie();
265335
int ans = 0;
266-
for (auto& word : s)
267-
ans += word.size() + 1;
336+
for (auto& w : words)
337+
{
338+
reverse(w.begin(), w.end());
339+
ans += trie->insert(w);
340+
}
268341
return ans;
269342
}
270343
};

0 commit comments

Comments
 (0)