Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 30a1628

Browse files
authored
feat: add solutions to lc problem: No.0748 (doocs#2110)
No.0748.Shortest Completing Word
1 parent 0d35c05 commit 30a1628

File tree

9 files changed

+465
-315
lines changed

9 files changed

+465
-315
lines changed

solution/0700-0799/0748.Shortest Completing Word/README.md

Lines changed: 152 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,14 @@
5252

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

55+
**方法一:计数**
56+
57+
我们先用哈希表或者一个长度为 $26$ 的数组 $cnt$ 统计字符串 `licensePlate` 中每个字母出现的次数,注意这里我们统一将字母转换为小写进行计数。
58+
59+
然后,我们遍历数组 `words` 中的每个单词 $w$,如果单词 $w$ 的长度比答案 $ans$ 的长度长,那么我们直接跳过该单词。否则,我们再用哈希表或者一个长度为 $26$ 的数组 $t$ 统计单词 $w$ 中每个字母出现的次数。如果对于任意一个字母,$t$ 中该字母出现的次数小于 $cnt$ 中该字母出现的次数,那么我们也可以直接跳过该单词。否则,我们就找到了一个满足条件的单词,我们更新答案 $ans$ 为当前单词 $w$。
60+
61+
时间复杂度 $O(n \times |\Sigma|)$,空间复杂度 $O(|\Sigma|)$,其中 $n$ 是数组 `words` 的长度,而 $\Sigma$ 是字符集,这里字符集为所有小写字母,因此 $|\Sigma| = 26$。
62+
5563
<!-- tabs:start -->
5664

5765
### **Python3**
@@ -61,27 +69,14 @@
6169
```python
6270
class Solution:
6371
def shortestCompletingWord(self, licensePlate: str, words: List[str]) -> str:
64-
def count(word):
65-
counter = [0] * 26
66-
for c in word:
67-
counter[ord(c) - ord('a')] += 1
68-
return counter
69-
70-
def check(counter1, counter2):
71-
for i in range(26):
72-
if counter1[i] > counter2[i]:
73-
return False
74-
return True
75-
76-
counter = count(c.lower() for c in licensePlate if c.isalpha())
77-
ans, n = None, 16
78-
for word in words:
79-
if n <= len(word):
72+
cnt = Counter(c.lower() for c in licensePlate if c.isalpha())
73+
ans = None
74+
for w in words:
75+
if ans and len(w) >= len(ans):
8076
continue
81-
t = count(word)
82-
if check(counter, t):
83-
n = len(word)
84-
ans = word
77+
t = Counter(w)
78+
if all(v <= t[c] for c, v in cnt.items()):
79+
ans = w
8580
return ans
8681
```
8782

@@ -92,39 +87,34 @@ class Solution:
9287
```java
9388
class Solution {
9489
public String shortestCompletingWord(String licensePlate, String[] words) {
95-
int[] counter = count(licensePlate.toLowerCase());
96-
String ans = null;
97-
int n = 16;
98-
for (String word : words) {
99-
if (n <= word.length()) {
90+
int[] cnt = new int[26];
91+
for (int i = 0; i < licensePlate.length(); ++i) {
92+
char c = licensePlate.charAt(i);
93+
if (Character.isLetter(c)) {
94+
cnt[Character.toLowerCase(c) - 'a']++;
95+
}
96+
}
97+
String ans = "";
98+
for (String w : words) {
99+
if (!ans.isEmpty() && w.length() >= ans.length()) {
100100
continue;
101101
}
102-
int[] t = count(word);
103-
if (check(counter, t)) {
104-
n = word.length();
105-
ans = word;
102+
int[] t = new int[26];
103+
for (int i = 0; i < w.length(); ++i) {
104+
t[w.charAt(i) - 'a']++;
106105
}
107-
}
108-
return ans;
109-
}
110-
111-
private int[] count(String word) {
112-
int[] counter = new int[26];
113-
for (char c : word.toCharArray()) {
114-
if (Character.isLetter(c)) {
115-
++counter[c - 'a'];
106+
boolean ok = true;
107+
for (int i = 0; i < 26; ++i) {
108+
if (t[i] < cnt[i]) {
109+
ok = false;
110+
break;
111+
}
116112
}
117-
}
118-
return counter;
119-
}
120-
121-
private boolean check(int[] counter1, int[] counter2) {
122-
for (int i = 0; i < 26; ++i) {
123-
if (counter1[i] > counter2[i]) {
124-
return false;
113+
if (ok) {
114+
ans = w;
125115
}
126116
}
127-
return true;
117+
return ans;
128118
}
129119
}
130120
```
@@ -135,74 +125,138 @@ class Solution {
135125
class Solution {
136126
public:
137127
string shortestCompletingWord(string licensePlate, vector<string>& words) {
138-
vector<int> counter = count(licensePlate);
139-
int n = 16;
128+
int cnt[26]{};
129+
for (char& c : licensePlate) {
130+
if (isalpha(c)) {
131+
++cnt[tolower(c) - 'a'];
132+
}
133+
}
140134
string ans;
141-
for (auto& word : words) {
142-
if (n <= word.size()) continue;
143-
vector<int> t = count(word);
144-
if (check(counter, t)) {
145-
n = word.size();
146-
ans = word;
135+
for (auto& w : words) {
136+
if (ans.size() && ans.size() <= w.size()) {
137+
continue;
138+
}
139+
int t[26]{};
140+
for (char& c : w) {
141+
++t[c - 'a'];
142+
}
143+
bool ok = true;
144+
for (int i = 0; i < 26; ++i) {
145+
if (cnt[i] > t[i]) {
146+
ok = false;
147+
break;
148+
}
149+
}
150+
if (ok) {
151+
ans = w;
147152
}
148153
}
149154
return ans;
150155
}
151-
152-
vector<int> count(string& word) {
153-
vector<int> counter(26);
154-
for (char& c : word)
155-
if (isalpha(c))
156-
++counter[tolower(c) - 'a'];
157-
return counter;
158-
}
159-
160-
bool check(vector<int>& counter1, vector<int>& counter2) {
161-
for (int i = 0; i < 26; ++i)
162-
if (counter1[i] > counter2[i])
163-
return false;
164-
return true;
165-
}
166156
};
167157
```
168158
169159
### **Go**
170160
171161
```go
172-
func shortestCompletingWord(licensePlate string, words []string) string {
173-
count := func(word string) []int {
174-
counter := make([]int, 26)
175-
for _, c := range word {
176-
if unicode.IsLetter(c) {
177-
counter[c-'a']++
178-
}
179-
}
180-
return counter
181-
}
182-
183-
check := func(cnt1, cnt2 []int) bool {
184-
for i := 0; i < 26; i++ {
185-
if cnt1[i] > cnt2[i] {
186-
return false
187-
}
162+
func shortestCompletingWord(licensePlate string, words []string) (ans string) {
163+
cnt := [26]int{}
164+
for _, c := range licensePlate {
165+
if unicode.IsLetter(c) {
166+
cnt[unicode.ToLower(c)-'a']++
188167
}
189-
return true
190168
}
191-
192-
counter := count(strings.ToLower(licensePlate))
193-
var ans string
194-
n := 16
195-
for _, word := range words {
196-
if n <= len(word) {
169+
for _, w := range words {
170+
if len(ans) > 0 && len(ans) <= len(w) {
197171
continue
198172
}
199-
t := count(word)
200-
if check(counter, t) {
201-
n = len(word)
202-
ans = word
173+
t := [26]int{}
174+
for _, c := range w {
175+
t[c-'a']++
176+
}
177+
ok := true
178+
for i, v := range cnt {
179+
if t[i] < v {
180+
ok = false
181+
break
182+
}
183+
}
184+
if ok {
185+
ans = w
203186
}
204187
}
205-
return ans
188+
return
189+
}
190+
```
191+
192+
### **TypeScript**
193+
194+
```ts
195+
function shortestCompletingWord(licensePlate: string, words: string[]): string {
196+
const cnt: number[] = Array(26).fill(0);
197+
for (const c of licensePlate) {
198+
const i = c.toLowerCase().charCodeAt(0) - 97;
199+
if (0 <= i && i < 26) {
200+
++cnt[i];
201+
}
202+
}
203+
let ans = '';
204+
for (const w of words) {
205+
if (ans.length && ans.length <= w.length) {
206+
continue;
207+
}
208+
const t = Array(26).fill(0);
209+
for (const c of w) {
210+
++t[c.charCodeAt(0) - 97];
211+
}
212+
let ok = true;
213+
for (let i = 0; i < 26; ++i) {
214+
if (t[i] < cnt[i]) {
215+
ok = false;
216+
break;
217+
}
218+
}
219+
if (ok) {
220+
ans = w;
221+
}
222+
}
223+
return ans;
224+
}
225+
```
226+
227+
### **Rust**
228+
229+
```rust
230+
impl Solution {
231+
pub fn shortest_completing_word(license_plate: String, words: Vec<String>) -> String {
232+
let mut cnt = vec![0; 26];
233+
for c in license_plate.chars() {
234+
if c.is_ascii_alphabetic() {
235+
cnt[((c.to_ascii_lowercase() as u8) - b'a') as usize] += 1;
236+
}
237+
}
238+
let mut ans = String::new();
239+
for w in words {
240+
if !ans.is_empty() && w.len() >= ans.len() {
241+
continue;
242+
}
243+
let mut t = vec![0; 26];
244+
for c in w.chars() {
245+
t[((c as u8) - b'a') as usize] += 1;
246+
}
247+
let mut ok = true;
248+
for i in 0..26 {
249+
if t[i] < cnt[i] {
250+
ok = false;
251+
break;
252+
}
253+
}
254+
if ok {
255+
ans = w;
256+
}
257+
}
258+
ans
259+
}
206260
}
207261
```
208262

0 commit comments

Comments
 (0)