Skip to content

Commit b2ac492

Browse files
committed
feat: add solutions to lc problem: NO.1178
No.1178.Number of Valid Words for Each Puzzle
1 parent 2ed50d7 commit b2ac492

File tree

7 files changed

+424
-2
lines changed

7 files changed

+424
-2
lines changed

solution/1100-1199/1178.Number of Valid Words for Each Puzzle/README.md

Lines changed: 154 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,175 @@ puzzles = ["aboveyz","abrodyz","abslute","absoryz","actresz","gaswxyz"]
5353

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

56+
**方法一:状态压缩 + 哈希表 + 子集枚举**
57+
58+
根据题目描述,对于字谜数组 $puzzles$ 中的每一个字谜 $p$,我们需要统计有多少个单词 $w$ 包含了字谜 $p$ 的第一个字母,且 $w$ 的每一个字母都可以在 $p$ 中找到。
59+
60+
由于每个单词重复的字母只需要统计一次,因此,我们可以使用二进制状态压缩的方法,将每个单词 $w$ 转换成一个二进制数 $mask$,其中 $mask$ 的第 $i$ 位为 $1$,当且仅当字母 $i$ 在单词 $w$ 中出现过。我们用哈希表 $cnt$ 统计所有单词的状态压缩后的值出现的次数。
61+
62+
接下来,遍历字谜数组 $puzzles$,对于每一个字谜 $p$,我们注意到其长度固定为 $7$,因此我们只需要枚举 $p$ 的子集,如果该子集包含 $p$ 的第一个字母,那么我们查找其在哈希表中对应的值并累加到当前字谜的答案中。
63+
64+
遍历结束后,我们就可以得到字谜数组 $puzzles$ 中每个字谜对应的谜底数量,将其返回即可。
65+
66+
时间复杂度 $O(m \times |w| + n \times 2^{|p|})$,空间复杂度 $O(m)$。其中 $m$ 和 $n$ 分别为数组 $words$ 和 $puzzles$ 的长度,而 $|w|$ 和 $|p|$ 分别为数组 $words$ 中单词的最大长度和数组 $puzzles$ 中字谜的长度。
67+
5668
<!-- tabs:start -->
5769

5870
### **Python3**
5971

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

6274
```python
63-
75+
class Solution:
76+
def findNumOfValidWords(self, words: List[str], puzzles: List[str]) -> List[int]:
77+
cnt = Counter()
78+
for w in words:
79+
mask = 0
80+
for c in w:
81+
mask |= 1 << (ord(c) - ord("a"))
82+
cnt[mask] += 1
83+
84+
ans = []
85+
for p in puzzles:
86+
mask = 0
87+
for c in p:
88+
mask |= 1 << (ord(c) - ord("a"))
89+
x, i, j = 0, ord(p[0]) - ord("a"), mask
90+
while j:
91+
if j >> i & 1:
92+
x += cnt[j]
93+
j = (j - 1) & mask
94+
ans.append(x)
95+
return ans
6496
```
6597

6698
### **Java**
6799

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

70102
```java
103+
class Solution {
104+
public List<Integer> findNumOfValidWords(String[] words, String[] puzzles) {
105+
Map<Integer, Integer> cnt = new HashMap<>(words.length);
106+
for (var w : words) {
107+
int mask = 0;
108+
for (int i = 0; i < w.length(); ++i) {
109+
mask |= 1 << (w.charAt(i) - 'a');
110+
}
111+
cnt.merge(mask, 1, Integer::sum);
112+
}
113+
List<Integer> ans = new ArrayList<>();
114+
for (var p : puzzles) {
115+
int mask = 0;
116+
for (int i = 0; i < p.length(); ++i) {
117+
mask |= 1 << (p.charAt(i) - 'a');
118+
}
119+
int x = 0;
120+
int i = p.charAt(0) - 'a';
121+
for (int j = mask; j > 0; j = (j - 1) & mask) {
122+
if ((j >> i & 1) == 1) {
123+
x += cnt.getOrDefault(j, 0);
124+
}
125+
}
126+
ans.add(x);
127+
}
128+
return ans;
129+
}
130+
}
131+
```
132+
133+
### **C++**
134+
135+
```cpp
136+
class Solution {
137+
public:
138+
vector<int> findNumOfValidWords(vector<string>& words, vector<string>& puzzles) {
139+
unordered_map<int, int> cnt;
140+
for (auto& w : words) {
141+
int mask = 0;
142+
for (char& c : w) {
143+
mask |= 1 << (c - 'a');
144+
}
145+
cnt[mask]++;
146+
}
147+
vector<int> ans;
148+
for (auto& p : puzzles) {
149+
int mask = 0;
150+
for (char& c : p) {
151+
mask |= 1 << (c - 'a');
152+
}
153+
int x = 0;
154+
int i = p[0] - 'a';
155+
for (int j = mask; j; j = (j - 1) & mask) {
156+
if (j >> i & 1) {
157+
x += cnt[j];
158+
}
159+
}
160+
ans.push_back(x);
161+
}
162+
return ans;
163+
}
164+
};
165+
```
166+
167+
### **Go**
168+
169+
```go
170+
func findNumOfValidWords(words []string, puzzles []string) (ans []int) {
171+
cnt := map[int]int{}
172+
for _, w := range words {
173+
mask := 0
174+
for _, c := range w {
175+
mask |= 1 << (c - 'a')
176+
}
177+
cnt[mask]++
178+
}
179+
for _, p := range puzzles {
180+
mask := 0
181+
for _, c := range p {
182+
mask |= 1 << (c - 'a')
183+
}
184+
x, i := 0, p[0]-'a'
185+
for j := mask; j > 0; j = (j - 1) & mask {
186+
if j>>i&1 > 0 {
187+
x += cnt[j]
188+
}
189+
}
190+
ans = append(ans, x)
191+
}
192+
return
193+
}
194+
```
71195

196+
### **TypeScript**
197+
198+
```ts
199+
function findNumOfValidWords(words: string[], puzzles: string[]): number[] {
200+
const cnt: Map<number, number> = new Map();
201+
for (const w of words) {
202+
let mask = 0;
203+
for (const c of w) {
204+
mask |= 1 << (c.charCodeAt(0) - 97);
205+
}
206+
cnt.set(mask, (cnt.get(mask) || 0) + 1);
207+
}
208+
const ans: number[] = [];
209+
for (const p of puzzles) {
210+
let mask = 0;
211+
for (const c of p) {
212+
mask |= 1 << (c.charCodeAt(0) - 97);
213+
}
214+
let x = 0;
215+
const i = p.charCodeAt(0) - 97;
216+
for (let j = mask; j; j = (j - 1) & mask) {
217+
if ((j >> i) & 1) {
218+
x += cnt.get(j) || 0;
219+
}
220+
}
221+
ans.push(x);
222+
}
223+
return ans;
224+
}
72225
```
73226

74227
### **...**

solution/1100-1199/1178.Number of Valid Words for Each Puzzle/README_EN.md

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,154 @@ There are no valid words for &quot;gaswxyz&quot; cause none of the words in the
5757
### **Python3**
5858

5959
```python
60-
60+
class Solution:
61+
def findNumOfValidWords(self, words: List[str], puzzles: List[str]) -> List[int]:
62+
cnt = Counter()
63+
for w in words:
64+
mask = 0
65+
for c in w:
66+
mask |= 1 << (ord(c) - ord("a"))
67+
cnt[mask] += 1
68+
69+
ans = []
70+
for p in puzzles:
71+
mask = 0
72+
for c in p:
73+
mask |= 1 << (ord(c) - ord("a"))
74+
x, i, j = 0, ord(p[0]) - ord("a"), mask
75+
while j:
76+
if j >> i & 1:
77+
x += cnt[j]
78+
j = (j - 1) & mask
79+
ans.append(x)
80+
return ans
6181
```
6282

6383
### **Java**
6484

6585
```java
86+
class Solution {
87+
public List<Integer> findNumOfValidWords(String[] words, String[] puzzles) {
88+
Map<Integer, Integer> cnt = new HashMap<>(words.length);
89+
for (var w : words) {
90+
int mask = 0;
91+
for (int i = 0; i < w.length(); ++i) {
92+
mask |= 1 << (w.charAt(i) - 'a');
93+
}
94+
cnt.merge(mask, 1, Integer::sum);
95+
}
96+
List<Integer> ans = new ArrayList<>();
97+
for (var p : puzzles) {
98+
int mask = 0;
99+
for (int i = 0; i < p.length(); ++i) {
100+
mask |= 1 << (p.charAt(i) - 'a');
101+
}
102+
int x = 0;
103+
int i = p.charAt(0) - 'a';
104+
for (int j = mask; j > 0; j = (j - 1) & mask) {
105+
if ((j >> i & 1) == 1) {
106+
x += cnt.getOrDefault(j, 0);
107+
}
108+
}
109+
ans.add(x);
110+
}
111+
return ans;
112+
}
113+
}
114+
```
115+
116+
### **C++**
117+
118+
```cpp
119+
class Solution {
120+
public:
121+
vector<int> findNumOfValidWords(vector<string>& words, vector<string>& puzzles) {
122+
unordered_map<int, int> cnt;
123+
for (auto& w : words) {
124+
int mask = 0;
125+
for (char& c : w) {
126+
mask |= 1 << (c - 'a');
127+
}
128+
cnt[mask]++;
129+
}
130+
vector<int> ans;
131+
for (auto& p : puzzles) {
132+
int mask = 0;
133+
for (char& c : p) {
134+
mask |= 1 << (c - 'a');
135+
}
136+
int x = 0;
137+
int i = p[0] - 'a';
138+
for (int j = mask; j; j = (j - 1) & mask) {
139+
if (j >> i & 1) {
140+
x += cnt[j];
141+
}
142+
}
143+
ans.push_back(x);
144+
}
145+
return ans;
146+
}
147+
};
148+
```
149+
150+
### **Go**
151+
152+
```go
153+
func findNumOfValidWords(words []string, puzzles []string) (ans []int) {
154+
cnt := map[int]int{}
155+
for _, w := range words {
156+
mask := 0
157+
for _, c := range w {
158+
mask |= 1 << (c - 'a')
159+
}
160+
cnt[mask]++
161+
}
162+
for _, p := range puzzles {
163+
mask := 0
164+
for _, c := range p {
165+
mask |= 1 << (c - 'a')
166+
}
167+
x, i := 0, p[0]-'a'
168+
for j := mask; j > 0; j = (j - 1) & mask {
169+
if j>>i&1 > 0 {
170+
x += cnt[j]
171+
}
172+
}
173+
ans = append(ans, x)
174+
}
175+
return
176+
}
177+
```
66178

179+
### **TypeScript**
180+
181+
```ts
182+
function findNumOfValidWords(words: string[], puzzles: string[]): number[] {
183+
const cnt: Map<number, number> = new Map();
184+
for (const w of words) {
185+
let mask = 0;
186+
for (const c of w) {
187+
mask |= 1 << (c.charCodeAt(0) - 97);
188+
}
189+
cnt.set(mask, (cnt.get(mask) || 0) + 1);
190+
}
191+
const ans: number[] = [];
192+
for (const p of puzzles) {
193+
let mask = 0;
194+
for (const c of p) {
195+
mask |= 1 << (c.charCodeAt(0) - 97);
196+
}
197+
let x = 0;
198+
const i = p.charCodeAt(0) - 97;
199+
for (let j = mask; j; j = (j - 1) & mask) {
200+
if ((j >> i) & 1) {
201+
x += cnt.get(j) || 0;
202+
}
203+
}
204+
ans.push(x);
205+
}
206+
return ans;
207+
}
67208
```
68209

69210
### **...**
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class Solution {
2+
public:
3+
vector<int> findNumOfValidWords(vector<string>& words, vector<string>& puzzles) {
4+
unordered_map<int, int> cnt;
5+
for (auto& w : words) {
6+
int mask = 0;
7+
for (char& c : w) {
8+
mask |= 1 << (c - 'a');
9+
}
10+
cnt[mask]++;
11+
}
12+
vector<int> ans;
13+
for (auto& p : puzzles) {
14+
int mask = 0;
15+
for (char& c : p) {
16+
mask |= 1 << (c - 'a');
17+
}
18+
int x = 0;
19+
int i = p[0] - 'a';
20+
for (int j = mask; j; j = (j - 1) & mask) {
21+
if (j >> i & 1) {
22+
x += cnt[j];
23+
}
24+
}
25+
ans.push_back(x);
26+
}
27+
return ans;
28+
}
29+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
func findNumOfValidWords(words []string, puzzles []string) (ans []int) {
2+
cnt := map[int]int{}
3+
for _, w := range words {
4+
mask := 0
5+
for _, c := range w {
6+
mask |= 1 << (c - 'a')
7+
}
8+
cnt[mask]++
9+
}
10+
for _, p := range puzzles {
11+
mask := 0
12+
for _, c := range p {
13+
mask |= 1 << (c - 'a')
14+
}
15+
x, i := 0, p[0]-'a'
16+
for j := mask; j > 0; j = (j - 1) & mask {
17+
if j>>i&1 > 0 {
18+
x += cnt[j]
19+
}
20+
}
21+
ans = append(ans, x)
22+
}
23+
return
24+
}

0 commit comments

Comments
 (0)