Skip to content

Commit c3e2625

Browse files
committed
feat: add solutions to lc problem: No.1684
No.1684.Count the Number of Consistent Strings
1 parent 52c4569 commit c3e2625

File tree

6 files changed

+271
-159
lines changed

6 files changed

+271
-159
lines changed

solution/1600-1699/1684.Count the Number of Consistent Strings/README.md

Lines changed: 124 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,22 @@
5252

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

55+
**方法一:哈希表或数组**
56+
57+
一种比较直接的思路是,用哈希表或数组 $s$ 记录 `allowed` 中的字符。然后遍历 `words` 数组,对于每个字符串 $w$,判断其是否由 `allowed` 中的字符组成。若是,答案加一。
58+
59+
时间复杂度 $O(n)$,空间复杂度 $O(C)$。其中 $n$ 为 `words` 数组的长度,而 $C$ 为 `allowed` 字符集的大小。本题中 $C \leq 26$。
60+
61+
**方法二:位运算**
62+
63+
我们也可以仅用一个整数来表示每个字符串中字符的出现情况。其中,整数的二进制表示中的每一位表示一个字符是否出现。
64+
65+
我们简单地定义一个函数 $f(w)$,这个函数可以将一个字符串 $w$ 转换为一个整数。整数的二进制表示中的每一位表示一个字符是否出现。例如,字符串 `ab` 可以转换为整数 $3$,即二进制表示为 $11$。字符串 `abd` 可以转换为整数 $11$,即二进制表示为 $1011$。
66+
67+
回到题目上,判断一个字符串 $w$ 是否由 `allowed` 中的字符组成,就可以转换为:判断 $f(allowed)$ 和 $f(w)$ 进行按位或运算后的结果是否等于 $f(allowed)$。若是,答案加一。
68+
69+
时间复杂度 $O(n)$,空间复杂度 $O(1)$。
70+
5571
<!-- tabs:start -->
5672

5773
### **Python3**
@@ -61,17 +77,18 @@
6177
```python
6278
class Solution:
6379
def countConsistentStrings(self, allowed: str, words: List[str]) -> int:
64-
res = 0
65-
chars = set(allowed)
66-
for word in words:
67-
find = True
68-
for c in word:
69-
if c not in chars:
70-
find = False
71-
break
72-
if find:
73-
res += 1
74-
return res
80+
s = set(allowed)
81+
return sum(all(c in s for c in w) for w in words)
82+
```
83+
84+
```python
85+
class Solution:
86+
def countConsistentStrings(self, allowed: str, words: List[str]) -> int:
87+
def f(w):
88+
return reduce(or_, (1 << (ord(c) - ord('a')) for c in w))
89+
90+
mask = f(allowed)
91+
return sum((mask | f(w)) == mask for w in words)
7592
```
7693

7794
### **Java**
@@ -81,24 +98,49 @@ class Solution:
8198
```java
8299
class Solution {
83100
public int countConsistentStrings(String allowed, String[] words) {
84-
boolean[] chars = new boolean[26];
101+
boolean[] s = new boolean[26];
85102
for (char c : allowed.toCharArray()) {
86-
chars[c - 'a'] = true;
103+
s[c - 'a'] = true;
104+
}
105+
int ans = 0;
106+
for (String w : words) {
107+
if (check(w, s)) {
108+
++ans;
109+
}
87110
}
88-
int res = 0;
89-
for (String word : words) {
90-
boolean find = true;
91-
for (char c : word.toCharArray()) {
92-
if (!chars[c - 'a']) {
93-
find = false;
94-
break;
95-
}
111+
return ans;
112+
}
113+
114+
private boolean check(String w, boolean[] s) {
115+
for (int i = 0; i < w.length(); ++i) {
116+
if (!s[w.charAt(i) - 'a']) {
117+
return false;
96118
}
97-
if (find) {
98-
++res;
119+
}
120+
return true;
121+
}
122+
}
123+
```
124+
125+
```java
126+
class Solution {
127+
public int countConsistentStrings(String allowed, String[] words) {
128+
int mask = f(allowed);
129+
int ans = 0;
130+
for (String w : words) {
131+
if ((mask | f(w)) == mask) {
132+
++ans;
99133
}
100134
}
101-
return res;
135+
return ans;
136+
}
137+
138+
private int f(String w) {
139+
int mask = 0;
140+
for (int i = 0; i < w.length(); ++i) {
141+
mask |= 1 << (w.charAt(i) - 'a');
142+
}
143+
return mask;
102144
}
103145
}
104146
```
@@ -109,48 +151,77 @@ class Solution {
109151
class Solution {
110152
public:
111153
int countConsistentStrings(string allowed, vector<string>& words) {
112-
vector<bool> chars(26, false);
113-
for (char c : allowed) {
114-
chars[c - 'a'] = true;
115-
}
116-
int res = 0;
117-
for (string word : words) {
118-
bool find = true;
119-
for (char c : word) {
120-
if (!chars[c - 'a']) {
121-
find = false;
122-
break;
123-
}
124-
}
125-
if (find) ++res;
126-
}
127-
return res;
154+
bitset<26> s;
155+
for (auto& c : allowed) s[c - 'a'] = 1;
156+
int ans = 0;
157+
auto check = [&](string& w) {
158+
for (auto& c : w) if (!s[c - 'a']) return false;
159+
return true;
160+
};
161+
for (auto& w : words) ans += check(w);
162+
return ans;
163+
}
164+
};
165+
```
166+
167+
```cpp
168+
class Solution {
169+
public:
170+
int countConsistentStrings(string allowed, vector<string>& words) {
171+
auto f = [](string& w) {
172+
int mask = 0;
173+
for (auto& c : w) mask |= 1 << (c - 'a');
174+
return mask;
175+
};
176+
int mask = f(allowed);
177+
int ans = 0;
178+
for (auto& w : words) ans += (mask | f(w)) == mask;
179+
return ans;
128180
}
129181
};
130182
```
131183

132184
### **Go**
133185

134186
```go
135-
func countConsistentStrings(allowed string, words []string) int {
136-
chars := [26]bool{}
187+
func countConsistentStrings(allowed string, words []string) (ans int) {
188+
s := [26]bool{}
137189
for _, c := range allowed {
138-
chars[c-'a'] = true
190+
s[c-'a'] = true
139191
}
140-
res := 0
141-
for _, word := range words {
142-
find := true
143-
for _, c := range word {
144-
if !chars[c-'a'] {
145-
find = false
146-
break
192+
check := func(w string) bool {
193+
for _, c := range w {
194+
if !s[c-'a'] {
195+
return false
147196
}
148197
}
149-
if find {
150-
res++
198+
return true
199+
}
200+
for _, w := range words {
201+
if check(w) {
202+
ans++
203+
}
204+
}
205+
return ans
206+
}
207+
```
208+
209+
```go
210+
func countConsistentStrings(allowed string, words []string) (ans int) {
211+
f := func(w string) (mask int) {
212+
for _, c := range w {
213+
mask |= 1 << (c - 'a')
214+
}
215+
return
216+
}
217+
218+
mask := f(allowed)
219+
for _, w := range words {
220+
if (mask | f(w)) == mask {
221+
ans++
151222
}
152223
}
153-
return res
224+
return
154225
}
155226
```
156227

0 commit comments

Comments
 (0)