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 61932c6

Browse files
feat: add solutions to lc problem: No.0288 (doocs#1976)
No.0288.Unique Word Abbreviation
1 parent c9fb852 commit 61932c6

File tree

7 files changed

+218
-127
lines changed

7 files changed

+218
-127
lines changed

‎solution/0200-0299/0288.Unique Word Abbreviation/README.md‎

Lines changed: 77 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,15 @@ validWordAbbr.isUnique("cake"); // 返回 true,因为 "cake" 已经存在于
6767

6868
<!-- 这里可写通用的实现逻辑 -->
6969

70-
哈希表实现,其中 key 存放单词缩写,value 存放单词缩写所对应的所有单词的集合。
70+
**方法一:哈希表**
71+
72+
根据题目描述,我们定义一个函数 $abbr(s),ドル它的功能是计算单词 $s$ 的缩写。如果单词 $s$ 的长度小于 3ドル,ドル那么它的缩写就是它本身;否则,它的缩写是它的首字母 + (它的长度 - 2) + 它的尾字母。
73+
74+
接下来,我们定义一个哈希表 $d,ドル它的键是单词的缩写,值是一个集合,集合中的元素是所有缩写为该键的单词。我们遍历给定的单词字典,对于字典中的每个单词 $s,ドル我们求出它的缩写 $abbr(s),ドル并将 $s$ 添加到 $d[abbr(s)]$ 中。
75+
76+
在判断单词 $word$ 是否满足题目要求时,我们求出它的缩写 $abbr(word),ドル如果 $abbr(word)$ 不在哈希表 $d$ 中,那么 $word$ 满足题目要求;否则,我们判断 $d[abbr(word)]$ 中是否只有一个元素,如果 $d[abbr(word)]$ 中只有一个元素且该元素就是 $word,ドル那么 $word$ 满足题目要求。
77+
78+
时间复杂度方面,初始化哈希表的时间复杂度是 $O(n),ドル其中 $n$ 是单词字典的长度;判断单词是否满足题目要求的时间复杂度是 $O(1)$。空间复杂度方面,哈希表的空间复杂度是 $O(n)$。
7179

7280
<!-- tabs:start -->
7381

@@ -78,18 +86,16 @@ validWordAbbr.isUnique("cake"); // 返回 true,因为 "cake" 已经存在于
7886
```python
7987
class ValidWordAbbr:
8088
def __init__(self, dictionary: List[str]):
81-
self.words = defaultdict(set)
82-
for word in dictionary:
83-
abbr = self.word_abbr(word)
84-
self.words[abbr].add(word)
89+
self.d = defaultdict(set)
90+
for s in dictionary:
91+
self.d[self.abbr(s)].add(s)
8592

8693
def isUnique(self, word: str) -> bool:
87-
abbr = self.word_abbr(word)
88-
words = self.words[abbr]
89-
return not words or (len(words) == 1 and word in words)
94+
s = self.abbr(word)
95+
return s not in self.d or all(word == t for t in self.d[s])
9096

91-
def word_abbr(self, s):
92-
return s if len(s) < 3 else f'{s[0]}{len(s) - 2}{s[-1]}'
97+
def abbr(self, s: str) -> str:
98+
return s if len(s) < 3 else s[0]+str(len(s) - 2) +s[-1]
9399

94100

95101
# Your ValidWordAbbr object will be instantiated and called as such:
@@ -103,25 +109,22 @@ class ValidWordAbbr:
103109

104110
```java
105111
class ValidWordAbbr {
106-
private Map<String, Set<String>> words;
112+
private Map<String, Set<String>> d =newHashMap<>();
107113

108114
public ValidWordAbbr(String[] dictionary) {
109-
words = new HashMap<>();
110-
for (String word : dictionary) {
111-
String abbr = abbr(word);
112-
words.computeIfAbsent(abbr, k -> new HashSet<>()).add(word);
115+
for (var s : dictionary) {
116+
d.computeIfAbsent(abbr(s), k -> new HashSet<>()).add(s);
113117
}
114118
}
115119

116120
public boolean isUnique(String word) {
117-
String abbr = abbr(word);
118-
Set<String> vals = words.get(abbr);
119-
return vals == null || (vals.size() == 1 && vals.contains(word));
121+
var ws = d.get(abbr(word));
122+
return ws == null || (ws.size() == 1 && ws.contains(word));
120123
}
121124

122125
private String abbr(String s) {
123126
int n = s.length();
124-
return n < 3 ? s : s.charAt(0) + Integer.toString(n - 2) + s.charAt(n - 1);
127+
return n < 3 ? s : s.substring(0, 1) + (n - 2) + s.substring(n - 1);
125128
}
126129
}
127130

@@ -137,23 +140,21 @@ class ValidWordAbbr {
137140
```cpp
138141
class ValidWordAbbr {
139142
public:
140-
unordered_map<string, unordered_set<string>> words;
141-
142143
ValidWordAbbr(vector<string>& dictionary) {
143-
for (auto word : dictionary) {
144-
auto abbr = wordAbbr(word);
145-
words[abbr].insert(word);
144+
for (auto& s : dictionary) {
145+
d[abbr(s)].insert(s);
146146
}
147147
}
148148

149149
bool isUnique(string word) {
150-
auto abbr = wordAbbr(word);
151-
if (!words.count(abbr)) return true;
152-
auto vals = words[abbr];
153-
return vals.size() == 1 && vals.count(word);
150+
string s = abbr(word);
151+
return !d.count(s) || (d[s].size() == 1 && d[s].count(word));
154152
}
155153

156-
string wordAbbr(string s) {
154+
private:
155+
unordered_map<string, unordered_set<string>> d;
156+
157+
string abbr(string& s) {
157158
int n = s.size();
158159
return n < 3 ? s : s.substr(0, 1) + to_string(n - 2) + s.substr(n - 1, 1);
159160
}
@@ -170,33 +171,32 @@ public:
170171
171172
```go
172173
type ValidWordAbbr struct {
173-
words map[string]map[string]bool
174+
d map[string]map[string]bool
174175
}
175176
176177
func Constructor(dictionary []string) ValidWordAbbr {
177-
words := make(map[string]map[string]bool)
178-
for _, word := range dictionary {
179-
abbr := wordAbbr(word)
180-
if words[abbr] == nil {
181-
words[abbr] = make(map[string]bool)
178+
d := make(map[string]map[string]bool)
179+
for _, s := range dictionary {
180+
abbr := abbr(s)
181+
if _, ok := d[abbr]; !ok {
182+
d[abbr] = make(map[string]bool)
182183
}
183-
words[abbr][word] = true
184+
d[abbr][s] = true
184185
}
185-
return ValidWordAbbr{words}
186+
return ValidWordAbbr{d}
186187
}
187188
188189
func (this *ValidWordAbbr) IsUnique(word string) bool {
189-
abbr := wordAbbr(word)
190-
words := this.words[abbr]
191-
return words == nil || (len(words) == 1 && words[word])
190+
ws := this.d[abbr(word)]
191+
return ws == nil || (len(ws) == 1 && ws[word])
192192
}
193193
194-
func wordAbbr(s string) string {
194+
func abbr(s string) string {
195195
n := len(s)
196-
if n <= 2 {
196+
if n < 3 {
197197
return s
198198
}
199-
return s[0:1] + strconv.Itoa(n-2) + s[n-1:]
199+
return fmt.Sprintf("%c%d%c", s[0], n-2, s[n-1])
200200
}
201201
202202
/**
@@ -206,6 +206,40 @@ func wordAbbr(s string) string {
206206
*/
207207
```
208208

209+
### **TypeScript**
210+
211+
```ts
212+
class ValidWordAbbr {
213+
private d: Map<string, Set<string>> = new Map();
214+
215+
constructor(dictionary: string[]) {
216+
for (const s of dictionary) {
217+
const abbr = this.abbr(s);
218+
if (!this.d.has(abbr)) {
219+
this.d.set(abbr, new Set());
220+
}
221+
this.d.get(abbr)!.add(s);
222+
}
223+
}
224+
225+
isUnique(word: string): boolean {
226+
const ws = this.d.get(this.abbr(word));
227+
return ws === undefined || (ws.size === 1 && ws.has(word));
228+
}
229+
230+
abbr(s: string): string {
231+
const n = s.length;
232+
return n < 3 ? s : s[0] + (n - 2) + s[n - 1];
233+
}
234+
}
235+
236+
/**
237+
* Your ValidWordAbbr object will be instantiated and called as such:
238+
* var obj = new ValidWordAbbr(dictionary)
239+
* var param_1 = obj.isUnique(word)
240+
*/
241+
```
242+
209243
### **...**
210244

211245
```

‎solution/0200-0299/0288.Unique Word Abbreviation/README_EN.md‎

Lines changed: 78 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -59,25 +59,33 @@ validWordAbbr.isUnique(&quot;cake&quot;); // return true, because &quot;cake&quo
5959

6060
## Solutions
6161

62+
**Solution 1: Hash Table**
63+
64+
According to the problem description, we define a function $abbr(s),ドル which calculates the abbreviation of the word $s$. If the length of the word $s$ is less than 3ドル,ドル then its abbreviation is itself; otherwise, its abbreviation is its first letter + (its length - 2) + its last letter.
65+
66+
Next, we define a hash table $d,ドル where the key is the abbreviation of the word, and the value is a set, the elements of which are all words abbreviated as that key. We traverse the given word dictionary, and for each word $s$ in the dictionary, we calculate its abbreviation $abbr(s),ドル and add $s$ to $d[abbr(s)]$.
67+
68+
When judging whether the word $word$ meets the requirements of the problem, we calculate its abbreviation $abbr(word)$. If $abbr(word)$ is not in the hash table $d,ドル then $word$ meets the requirements of the problem; otherwise, we judge whether there is only one element in $d[abbr(word)]$. If there is only one element in $d[abbr(word)]$ and that element is $word,ドル then $word$ meets the requirements of the problem.
69+
70+
In terms of time complexity, the time complexity of initializing the hash table is $O(n),ドル where $n$ is the length of the word dictionary; the time complexity of judging whether a word meets the requirements of the problem is $O(1)$. In terms of space complexity, the space complexity of the hash table is $O(n)$.
71+
6272
<!-- tabs:start -->
6373

6474
### **Python3**
6575

6676
```python
6777
class ValidWordAbbr:
6878
def __init__(self, dictionary: List[str]):
69-
self.words = defaultdict(set)
70-
for word in dictionary:
71-
abbr = self.word_abbr(word)
72-
self.words[abbr].add(word)
79+
self.d = defaultdict(set)
80+
for s in dictionary:
81+
self.d[self.abbr(s)].add(s)
7382

7483
def isUnique(self, word: str) -> bool:
75-
abbr = self.word_abbr(word)
76-
words = self.words[abbr]
77-
return not words or (len(words) == 1 and word in words)
84+
s = self.abbr(word)
85+
return s not in self.d or all(word == t for t in self.d[s])
7886

79-
def word_abbr(self, s):
80-
return s if len(s) < 3 else f'{s[0]}{len(s) - 2}{s[-1]}'
87+
def abbr(self, s: str) -> str:
88+
return s if len(s) < 3 else s[0]+str(len(s) - 2) +s[-1]
8189

8290

8391
# Your ValidWordAbbr object will be instantiated and called as such:
@@ -89,25 +97,22 @@ class ValidWordAbbr:
8997

9098
```java
9199
class ValidWordAbbr {
92-
private Map<String, Set<String>> words;
100+
private Map<String, Set<String>> d =newHashMap<>();
93101

94102
public ValidWordAbbr(String[] dictionary) {
95-
words = new HashMap<>();
96-
for (String word : dictionary) {
97-
String abbr = abbr(word);
98-
words.computeIfAbsent(abbr, k -> new HashSet<>()).add(word);
103+
for (var s : dictionary) {
104+
d.computeIfAbsent(abbr(s), k -> new HashSet<>()).add(s);
99105
}
100106
}
101107

102108
public boolean isUnique(String word) {
103-
String abbr = abbr(word);
104-
Set<String> vals = words.get(abbr);
105-
return vals == null || (vals.size() == 1 && vals.contains(word));
109+
var ws = d.get(abbr(word));
110+
return ws == null || (ws.size() == 1 && ws.contains(word));
106111
}
107112

108113
private String abbr(String s) {
109114
int n = s.length();
110-
return n < 3 ? s : s.charAt(0) + Integer.toString(n - 2) + s.charAt(n - 1);
115+
return n < 3 ? s : s.substring(0, 1) + (n - 2) + s.substring(n - 1);
111116
}
112117
}
113118

@@ -123,23 +128,21 @@ class ValidWordAbbr {
123128
```cpp
124129
class ValidWordAbbr {
125130
public:
126-
unordered_map<string, unordered_set<string>> words;
127-
128131
ValidWordAbbr(vector<string>& dictionary) {
129-
for (auto word : dictionary) {
130-
auto abbr = wordAbbr(word);
131-
words[abbr].insert(word);
132+
for (auto& s : dictionary) {
133+
d[abbr(s)].insert(s);
132134
}
133135
}
134136

135137
bool isUnique(string word) {
136-
auto abbr = wordAbbr(word);
137-
if (!words.count(abbr)) return true;
138-
auto vals = words[abbr];
139-
return vals.size() == 1 && vals.count(word);
138+
string s = abbr(word);
139+
return !d.count(s) || (d[s].size() == 1 && d[s].count(word));
140140
}
141141

142-
string wordAbbr(string s) {
142+
private:
143+
unordered_map<string, unordered_set<string>> d;
144+
145+
string abbr(string& s) {
143146
int n = s.size();
144147
return n < 3 ? s : s.substr(0, 1) + to_string(n - 2) + s.substr(n - 1, 1);
145148
}
@@ -156,33 +159,32 @@ public:
156159
157160
```go
158161
type ValidWordAbbr struct {
159-
words map[string]map[string]bool
162+
d map[string]map[string]bool
160163
}
161164
162165
func Constructor(dictionary []string) ValidWordAbbr {
163-
words := make(map[string]map[string]bool)
164-
for _, word := range dictionary {
165-
abbr := wordAbbr(word)
166-
if words[abbr] == nil {
167-
words[abbr] = make(map[string]bool)
166+
d := make(map[string]map[string]bool)
167+
for _, s := range dictionary {
168+
abbr := abbr(s)
169+
if _, ok := d[abbr]; !ok {
170+
d[abbr] = make(map[string]bool)
168171
}
169-
words[abbr][word] = true
172+
d[abbr][s] = true
170173
}
171-
return ValidWordAbbr{words}
174+
return ValidWordAbbr{d}
172175
}
173176
174177
func (this *ValidWordAbbr) IsUnique(word string) bool {
175-
abbr := wordAbbr(word)
176-
words := this.words[abbr]
177-
return words == nil || (len(words) == 1 && words[word])
178+
ws := this.d[abbr(word)]
179+
return ws == nil || (len(ws) == 1 && ws[word])
178180
}
179181
180-
func wordAbbr(s string) string {
182+
func abbr(s string) string {
181183
n := len(s)
182-
if n <= 2 {
184+
if n < 3 {
183185
return s
184186
}
185-
return s[0:1] + strconv.Itoa(n-2) + s[n-1:]
187+
return fmt.Sprintf("%c%d%c", s[0], n-2, s[n-1])
186188
}
187189
188190
/**
@@ -192,6 +194,40 @@ func wordAbbr(s string) string {
192194
*/
193195
```
194196

197+
### **TypeScript**
198+
199+
```ts
200+
class ValidWordAbbr {
201+
private d: Map<string, Set<string>> = new Map();
202+
203+
constructor(dictionary: string[]) {
204+
for (const s of dictionary) {
205+
const abbr = this.abbr(s);
206+
if (!this.d.has(abbr)) {
207+
this.d.set(abbr, new Set());
208+
}
209+
this.d.get(abbr)!.add(s);
210+
}
211+
}
212+
213+
isUnique(word: string): boolean {
214+
const ws = this.d.get(this.abbr(word));
215+
return ws === undefined || (ws.size === 1 && ws.has(word));
216+
}
217+
218+
abbr(s: string): string {
219+
const n = s.length;
220+
return n < 3 ? s : s[0] + (n - 2) + s[n - 1];
221+
}
222+
}
223+
224+
/**
225+
* Your ValidWordAbbr object will be instantiated and called as such:
226+
* var obj = new ValidWordAbbr(dictionary)
227+
* var param_1 = obj.isUnique(word)
228+
*/
229+
```
230+
195231
### **...**
196232

197233
```

0 commit comments

Comments
(0)

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