Skip to content

Commit 6c44148

Browse files
authored
feat: add solutions to lc problems: No.2135~2137 (doocs#3157)
* No.2135.Count Words Obtained After Adding a Letter * No.2136.Earliest Possible Day of Full Bloom * No.2137.Pour Water Between Buckets to Make Water Levels Equal
1 parent cf06249 commit 6c44148

File tree

9 files changed

+239
-169
lines changed

9 files changed

+239
-169
lines changed

solution/2100-2199/2135.Count Words Obtained After Adding a Letter/README.md

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,13 @@ tags:
8888

8989
<!-- solution:start -->
9090

91-
### 方法一
91+
### 方法一:哈希表 + 位运算
92+
93+
我们注意到,题目中给定的字符串只包含小写字母,并且每个字符串的字母至多出现一次。因此,我们可以用一个长度为 $26$ 的二进制数表示一个字符串,其中第 $i$ 位为 $1$ 表示字符串中包含第 $i$ 个小写字母,为 $0$ 表示字符串中不包含第 $i$ 个小写字母。
94+
95+
我们可以将字符串数组 $\text{startWords}$ 中的每个字符串转换为一个二进制数,并将这些二进制数存储到一个集合 $\text{s}$ 中。对于字符串数组 $\text{targetWords}$ 中的每个字符串,我们首先将其转换为一个二进制数,然后枚举这个字符串中的每个字母,将这个字母从二进制数中去掉,再检查是否存在一个二进制数在集合 $\text{s}$ 中,使得这个二进制数与去掉的字母的二进制数的异或结果在集合 $\text{s}$ 中,如果存在,那么这个字符串可以由 $\text{startWords}$ 中的某个字符串执行转换操作获得,答案加一。然后我们跳过这个字符串,继续处理下一个字符串。
96+
97+
时间复杂度 $O(n \times |\Sigma|)$,空间复杂度 $O(n)$。其中 $n$ 为字符串数组 $\text{targetWords}$ 的长度,而 $|\Sigma|$ 为字符串中的字符集大小,本题中 $|\Sigma| = 26$。
9298

9399
<!-- tabs:start -->
94100

@@ -97,21 +103,12 @@ tags:
97103
```python
98104
class Solution:
99105
def wordCount(self, startWords: List[str], targetWords: List[str]) -> int:
100-
s = set()
101-
for word in startWords:
102-
mask = 0
103-
for c in word:
104-
mask |= 1 << (ord(c) - ord('a'))
105-
s.add(mask)
106-
106+
s = {sum(1 << (ord(c) - 97) for c in w) for w in startWords}
107107
ans = 0
108-
for word in targetWords:
109-
mask = 0
110-
for c in word:
111-
mask |= 1 << (ord(c) - ord('a'))
112-
for c in word:
113-
t = mask ^ (1 << (ord(c) - ord('a')))
114-
if t in s:
108+
for w in targetWords:
109+
x = sum(1 << (ord(c) - 97) for c in w)
110+
for c in w:
111+
if x ^ (1 << (ord(c) - 97)) in s:
115112
ans += 1
116113
break
117114
return ans
@@ -121,25 +118,23 @@ class Solution:
121118

122119
```java
123120
class Solution {
124-
125121
public int wordCount(String[] startWords, String[] targetWords) {
126122
Set<Integer> s = new HashSet<>();
127-
for (String word : startWords) {
128-
int mask = 0;
129-
for (char c : word.toCharArray()) {
130-
mask |= (1 << (c - 'a'));
123+
for (var w : startWords) {
124+
int x = 0;
125+
for (var c : w.toCharArray()) {
126+
x |= 1 << (c - 'a');
131127
}
132-
s.add(mask);
128+
s.add(x);
133129
}
134130
int ans = 0;
135-
for (String word : targetWords) {
136-
int mask = 0;
137-
for (char c : word.toCharArray()) {
138-
mask |= (1 << (c - 'a'));
131+
for (var w : targetWords) {
132+
int x = 0;
133+
for (var c : w.toCharArray()) {
134+
x |= 1 << (c - 'a');
139135
}
140-
for (char c : word.toCharArray()) {
141-
int t = mask ^ (1 << (c - 'a'));
142-
if (s.contains(t)) {
136+
for (var c : w.toCharArray()) {
137+
if (s.contains(x ^ (1 << (c - 'a')))) {
143138
++ans;
144139
break;
145140
}
@@ -157,20 +152,21 @@ class Solution {
157152
public:
158153
int wordCount(vector<string>& startWords, vector<string>& targetWords) {
159154
unordered_set<int> s;
160-
for (auto& word : startWords) {
161-
int mask = 0;
162-
for (char c : word)
163-
mask |= (1 << (c - 'a'));
164-
s.insert(mask);
155+
for (auto& w : startWords) {
156+
int x = 0;
157+
for (char c : w) {
158+
x |= 1 << (c - 'a');
159+
}
160+
s.insert(x);
165161
}
166162
int ans = 0;
167-
for (auto& word : targetWords) {
168-
int mask = 0;
169-
for (char c : word)
170-
mask |= (1 << (c - 'a'));
171-
for (char c : word) {
172-
int t = mask ^ (1 << (c - 'a'));
173-
if (s.count(t)) {
163+
for (auto& w : targetWords) {
164+
int x = 0;
165+
for (char c : w) {
166+
x |= 1 << (c - 'a');
167+
}
168+
for (char c : w) {
169+
if (s.contains(x ^ (1 << (c - 'a')))) {
174170
++ans;
175171
break;
176172
}
@@ -184,30 +180,57 @@ public:
184180
#### Go
185181
186182
```go
187-
func wordCount(startWords []string, targetWords []string) int {
188-
s := make(map[int]bool)
189-
for _, word := range startWords {
190-
mask := 0
191-
for _, c := range word {
192-
mask |= (1 << (c - 'a'))
183+
func wordCount(startWords []string, targetWords []string) (ans int) {
184+
s := map[int]bool{}
185+
for _, w := range startWords {
186+
x := 0
187+
for _, c := range w {
188+
x |= 1 << (c - 'a')
193189
}
194-
s[mask] = true
190+
s[x] = true
195191
}
196-
ans := 0
197-
for _, word := range targetWords {
198-
mask := 0
199-
for _, c := range word {
200-
mask |= (1 << (c - 'a'))
192+
for _, w := range targetWords {
193+
x := 0
194+
for _, c := range w {
195+
x |= 1 << (c - 'a')
201196
}
202-
for _, c := range word {
203-
t := mask ^ (1 << (c - 'a'))
204-
if s[t] {
197+
for _, c := range w {
198+
if s[x^(1<<(c-'a'))] {
205199
ans++
206200
break
207201
}
208202
}
209203
}
210-
return ans
204+
return
205+
}
206+
```
207+
208+
#### TypeScript
209+
210+
```ts
211+
function wordCount(startWords: string[], targetWords: string[]): number {
212+
const s = new Set<number>();
213+
for (const w of startWords) {
214+
let x = 0;
215+
for (const c of w) {
216+
x ^= 1 << (c.charCodeAt(0) - 97);
217+
}
218+
s.add(x);
219+
}
220+
let ans = 0;
221+
for (const w of targetWords) {
222+
let x = 0;
223+
for (const c of w) {
224+
x ^= 1 << (c.charCodeAt(0) - 97);
225+
}
226+
for (const c of w) {
227+
if (s.has(x ^ (1 << (c.charCodeAt(0) - 97)))) {
228+
++ans;
229+
break;
230+
}
231+
}
232+
}
233+
return ans;
211234
}
212235
```
213236

solution/2100-2199/2135.Count Words Obtained After Adding a Letter/README_EN.md

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,13 @@ tags:
8686

8787
<!-- solution:start -->
8888

89-
### Solution 1
89+
### Solution 1: Hash Table + Bit Manipulation
90+
91+
We notice that the given strings only contain lowercase letters, and each letter in a string appears at most once. Therefore, we can represent a string with a binary number of length $26$, where the $i$-th bit being $1$ indicates that the string contains the $i$-th lowercase letter, and $0$ indicates the absence of the $i$-th lowercase letter.
92+
93+
We can convert each string in the array $\text{startWords}$ into a binary number and store these binary numbers in a set $\text{s}$. For each string in the array $\text{targetWords}$, we first convert it into a binary number, then enumerate each letter in this string, remove this letter from the binary number, and check if there exists a binary number in the set $\text{s}$ such that the XOR result of this binary number with the removed letter's binary number is in the set $\text{s}$. If such a binary number exists, then this string can be obtained by performing a transformation operation on some string in $\text{startWords}$, and we increment the answer by one. Then, we skip this string and continue processing the next string.
94+
95+
The time complexity is $O(n \times |\Sigma|)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string array $\text{targetWords}$, and $|\Sigma|$ is the size of the character set in the string, which is $26$ in this problem.
9096

9197
<!-- tabs:start -->
9298

@@ -95,21 +101,12 @@ tags:
95101
```python
96102
class Solution:
97103
def wordCount(self, startWords: List[str], targetWords: List[str]) -> int:
98-
s = set()
99-
for word in startWords:
100-
mask = 0
101-
for c in word:
102-
mask |= 1 << (ord(c) - ord('a'))
103-
s.add(mask)
104-
104+
s = {sum(1 << (ord(c) - 97) for c in w) for w in startWords}
105105
ans = 0
106-
for word in targetWords:
107-
mask = 0
108-
for c in word:
109-
mask |= 1 << (ord(c) - ord('a'))
110-
for c in word:
111-
t = mask ^ (1 << (ord(c) - ord('a')))
112-
if t in s:
106+
for w in targetWords:
107+
x = sum(1 << (ord(c) - 97) for c in w)
108+
for c in w:
109+
if x ^ (1 << (ord(c) - 97)) in s:
113110
ans += 1
114111
break
115112
return ans
@@ -119,25 +116,23 @@ class Solution:
119116

120117
```java
121118
class Solution {
122-
123119
public int wordCount(String[] startWords, String[] targetWords) {
124120
Set<Integer> s = new HashSet<>();
125-
for (String word : startWords) {
126-
int mask = 0;
127-
for (char c : word.toCharArray()) {
128-
mask |= (1 << (c - 'a'));
121+
for (var w : startWords) {
122+
int x = 0;
123+
for (var c : w.toCharArray()) {
124+
x |= 1 << (c - 'a');
129125
}
130-
s.add(mask);
126+
s.add(x);
131127
}
132128
int ans = 0;
133-
for (String word : targetWords) {
134-
int mask = 0;
135-
for (char c : word.toCharArray()) {
136-
mask |= (1 << (c - 'a'));
129+
for (var w : targetWords) {
130+
int x = 0;
131+
for (var c : w.toCharArray()) {
132+
x |= 1 << (c - 'a');
137133
}
138-
for (char c : word.toCharArray()) {
139-
int t = mask ^ (1 << (c - 'a'));
140-
if (s.contains(t)) {
134+
for (var c : w.toCharArray()) {
135+
if (s.contains(x ^ (1 << (c - 'a')))) {
141136
++ans;
142137
break;
143138
}
@@ -155,20 +150,21 @@ class Solution {
155150
public:
156151
int wordCount(vector<string>& startWords, vector<string>& targetWords) {
157152
unordered_set<int> s;
158-
for (auto& word : startWords) {
159-
int mask = 0;
160-
for (char c : word)
161-
mask |= (1 << (c - 'a'));
162-
s.insert(mask);
153+
for (auto& w : startWords) {
154+
int x = 0;
155+
for (char c : w) {
156+
x |= 1 << (c - 'a');
157+
}
158+
s.insert(x);
163159
}
164160
int ans = 0;
165-
for (auto& word : targetWords) {
166-
int mask = 0;
167-
for (char c : word)
168-
mask |= (1 << (c - 'a'));
169-
for (char c : word) {
170-
int t = mask ^ (1 << (c - 'a'));
171-
if (s.count(t)) {
161+
for (auto& w : targetWords) {
162+
int x = 0;
163+
for (char c : w) {
164+
x |= 1 << (c - 'a');
165+
}
166+
for (char c : w) {
167+
if (s.contains(x ^ (1 << (c - 'a')))) {
172168
++ans;
173169
break;
174170
}
@@ -182,30 +178,57 @@ public:
182178
#### Go
183179
184180
```go
185-
func wordCount(startWords []string, targetWords []string) int {
186-
s := make(map[int]bool)
187-
for _, word := range startWords {
188-
mask := 0
189-
for _, c := range word {
190-
mask |= (1 << (c - 'a'))
181+
func wordCount(startWords []string, targetWords []string) (ans int) {
182+
s := map[int]bool{}
183+
for _, w := range startWords {
184+
x := 0
185+
for _, c := range w {
186+
x |= 1 << (c - 'a')
191187
}
192-
s[mask] = true
188+
s[x] = true
193189
}
194-
ans := 0
195-
for _, word := range targetWords {
196-
mask := 0
197-
for _, c := range word {
198-
mask |= (1 << (c - 'a'))
190+
for _, w := range targetWords {
191+
x := 0
192+
for _, c := range w {
193+
x |= 1 << (c - 'a')
199194
}
200-
for _, c := range word {
201-
t := mask ^ (1 << (c - 'a'))
202-
if s[t] {
195+
for _, c := range w {
196+
if s[x^(1<<(c-'a'))] {
203197
ans++
204198
break
205199
}
206200
}
207201
}
208-
return ans
202+
return
203+
}
204+
```
205+
206+
#### TypeScript
207+
208+
```ts
209+
function wordCount(startWords: string[], targetWords: string[]): number {
210+
const s = new Set<number>();
211+
for (const w of startWords) {
212+
let x = 0;
213+
for (const c of w) {
214+
x ^= 1 << (c.charCodeAt(0) - 97);
215+
}
216+
s.add(x);
217+
}
218+
let ans = 0;
219+
for (const w of targetWords) {
220+
let x = 0;
221+
for (const c of w) {
222+
x ^= 1 << (c.charCodeAt(0) - 97);
223+
}
224+
for (const c of w) {
225+
if (s.has(x ^ (1 << (c.charCodeAt(0) - 97)))) {
226+
++ans;
227+
break;
228+
}
229+
}
230+
}
231+
return ans;
209232
}
210233
```
211234

0 commit comments

Comments
 (0)