Skip to content

Commit 3b44422

Browse files
authored
feat: add solutions to lc problem: No.1461 (#3353)
No.1461.Check If a String Contains All Binary Codes of Size K
1 parent f21c6da commit 3b44422

File tree

14 files changed

+360
-154
lines changed

14 files changed

+360
-154
lines changed

solution/1400-1499/1461.Check If a String Contains All Binary Codes of Size K/README.md

+112-50
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,11 @@ tags:
6868

6969
### 方法一:哈希表
7070

71-
遍历字符串 $s$,用一个哈希表存储所有长度为 $k$ 的不同子串。只需要判断子串数能否达到 $2^k$ 即可
71+
首先,对于一个长度为 $n$ 的字符串 $s$,长度为 $k$ 的子串的个数为 $n - k + 1$,如果 $n - k + 1 < 2^k$,则一定存在长度为 $k$ 的二进制串不是 $s$ 的子串,返回 `false`
7272

73-
时间复杂度 $O(n \times k)$,其中 $n$ 是字符串 $s$ 的长度,$k$ 是子串长度。
73+
接下来,我们遍历字符串 $s$,将所有长度为 $k$ 的子串存入集合 $ss$,最后判断集合 $ss$ 的大小是否等于 $2^k$。
74+
75+
时间复杂度 $O(n \times k)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。
7476

7577
<!-- tabs:start -->
7678

@@ -79,20 +81,29 @@ tags:
7981
```python
8082
class Solution:
8183
def hasAllCodes(self, s: str, k: int) -> bool:
82-
ss = {s[i : i + k] for i in range(len(s) - k + 1)}
83-
return len(ss) == 1 << k
84+
n = len(s)
85+
m = 1 << k
86+
if n - k + 1 < m:
87+
return False
88+
ss = {s[i : i + k] for i in range(n - k + 1)}
89+
return len(ss) == m
8490
```
8591

8692
#### Java
8793

8894
```java
8995
class Solution {
9096
public boolean hasAllCodes(String s, int k) {
97+
int n = s.length();
98+
int m = 1 << k;
99+
if (n - k + 1 < m) {
100+
return false;
101+
}
91102
Set<String> ss = new HashSet<>();
92-
for (int i = 0; i < s.length() - k + 1; ++i) {
103+
for (int i = 0; i < n - k + 1; ++i) {
93104
ss.add(s.substring(i, i + k));
94105
}
95-
return ss.size() == 1 << k;
106+
return ss.size() == m;
96107
}
97108
}
98109
```
@@ -103,11 +114,16 @@ class Solution {
103114
class Solution {
104115
public:
105116
bool hasAllCodes(string s, int k) {
117+
int n = s.size();
118+
int m = 1 << k;
119+
if (n - k + 1 < m) {
120+
return false;
121+
}
106122
unordered_set<string> ss;
107-
for (int i = 0; i + k <= s.size(); ++i) {
123+
for (int i = 0; i + k <= n; ++i) {
108124
ss.insert(move(s.substr(i, k)));
109125
}
110-
return ss.size() == 1 << k;
126+
return ss.size() == m;
111127
}
112128
};
113129
```
@@ -116,11 +132,32 @@ public:
116132
117133
```go
118134
func hasAllCodes(s string, k int) bool {
135+
n, m := len(s), 1<<k
136+
if n-k+1 < m {
137+
return false
138+
}
119139
ss := map[string]bool{}
120-
for i := 0; i+k <= len(s); i++ {
140+
for i := 0; i+k <= n; i++ {
121141
ss[s[i:i+k]] = true
122142
}
123-
return len(ss) == 1<<k
143+
return len(ss) == m
144+
}
145+
```
146+
147+
#### TypeScript
148+
149+
```ts
150+
function hasAllCodes(s: string, k: number): boolean {
151+
const n = s.length;
152+
const m = 1 << k;
153+
if (n - k + 1 < m) {
154+
return false;
155+
}
156+
const ss = new Set<string>();
157+
for (let i = 0; i + k <= n; ++i) {
158+
ss.add(s.slice(i, i + k));
159+
}
160+
return ss.size === m;
124161
}
125162
```
126163

@@ -132,9 +169,9 @@ func hasAllCodes(s string, k int) bool {
132169

133170
### 方法二:滑动窗口
134171

135-
方法一中,我们存储了所有长度为 $k$ 的不同子串,子串的处理需要 $O(k)$ 的时间,我们可以改用滑动窗口,每次添加最新字符时,删除窗口最左边的字符。此过程中用一个整型数字 $num$ 来存放子串。
172+
方法一中,我们存储了所有长度为 $k$ 的不同子串,子串的处理需要 $O(k)$ 的时间,我们可以改用滑动窗口,每次添加最新字符时,删除窗口最左边的字符。此过程中用一个整型数字 $x$ 来存放子串。
136173

137-
时间复杂度 $O(n)$,其中 $n$ 是字符串 $s$ 的长度。
174+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。
138175

139176
<!-- tabs:start -->
140177

@@ -143,17 +180,19 @@ func hasAllCodes(s string, k int) bool {
143180
```python
144181
class Solution:
145182
def hasAllCodes(self, s: str, k: int) -> bool:
146-
if len(s) - k + 1 < (1 << k):
183+
n = len(s)
184+
m = 1 << k
185+
if n - k + 1 < m:
147186
return False
148-
vis = [False] * (1 << k)
149-
num = int(s[:k], 2)
150-
vis[num] = True
151-
for i in range(k, len(s)):
152-
a = (ord(s[i - k]) - ord('0')) << (k - 1)
153-
b = ord(s[i]) - ord('0')
154-
num = ((num - a) << 1) + b
155-
vis[num] = True
156-
return all(v for v in vis)
187+
ss = set()
188+
x = int(s[:k], 2)
189+
ss.add(x)
190+
for i in range(k, n):
191+
a = int(s[i - k]) << (k - 1)
192+
b = int(s[i])
193+
x = (x - a) << 1 | b
194+
ss.add(x)
195+
return len(ss) == m
157196
```
158197

159198
#### Java
@@ -162,19 +201,20 @@ class Solution:
162201
class Solution {
163202
public boolean hasAllCodes(String s, int k) {
164203
int n = s.length();
165-
if (n - k + 1 < (1 << k)) {
204+
int m = 1 << k;
205+
if (n - k + 1 < m) {
166206
return false;
167207
}
168-
boolean[] vis = new boolean[1 << k];
169-
int num = Integer.parseInt(s.substring(0, k), 2);
170-
vis[num] = true;
208+
boolean[] ss = new boolean[m];
209+
int x = Integer.parseInt(s.substring(0, k), 2);
210+
ss[x] = true;
171211
for (int i = k; i < n; ++i) {
172212
int a = (s.charAt(i - k) - '0') << (k - 1);
173213
int b = s.charAt(i) - '0';
174-
num = (num - a) << 1 | b;
175-
vis[num] = true;
214+
x = (x - a) << 1 | b;
215+
ss[x] = true;
176216
}
177-
for (boolean v : vis) {
217+
for (boolean v : ss) {
178218
if (!v) {
179219
return false;
180220
}
@@ -191,19 +231,21 @@ class Solution {
191231
public:
192232
bool hasAllCodes(string s, int k) {
193233
int n = s.size();
194-
if (n - k + 1 < (1 << k)) return false;
195-
vector<bool> vis(1 << k);
196-
int num = stoi(s.substr(0, k), nullptr, 2);
197-
vis[num] = true;
234+
int m = 1 << k;
235+
if (n - k + 1 < m) {
236+
return false;
237+
}
238+
bool ss[m];
239+
memset(ss, false, sizeof(ss));
240+
int x = stoi(s.substr(0, k), nullptr, 2);
241+
ss[x] = true;
198242
for (int i = k; i < n; ++i) {
199243
int a = (s[i - k] - '0') << (k - 1);
200244
int b = s[i] - '0';
201-
num = (num - a) << 1 | b;
202-
vis[num] = true;
245+
x = (x - a) << 1 | b;
246+
ss[x] = true;
203247
}
204-
for (bool v : vis)
205-
if (!v) return false;
206-
return true;
248+
return all_of(ss, ss + m, [](bool v) { return v; });
207249
}
208250
};
209251
```
@@ -212,22 +254,20 @@ public:
212254
213255
```go
214256
func hasAllCodes(s string, k int) bool {
215-
n := len(s)
216-
if n-k+1 < (1 << k) {
257+
n, m := len(s), 1<<k
258+
if n-k+1 < m {
217259
return false
218260
}
219-
vis := make([]bool, 1<<k)
220-
num := 0
221-
for i := 0; i < k; i++ {
222-
num = num<<1 | int(s[i]-'0')
223-
}
224-
vis[num] = true
261+
ss := make([]bool, m)
262+
x, _ := strconv.ParseInt(s[:k], 2, 64)
263+
ss[x] = true
225264
for i := k; i < n; i++ {
226-
a := int(s[i-k]-'0') << (k - 1)
227-
num = (num-a)<<1 | int(s[i]-'0')
228-
vis[num] = true
265+
a := int64(s[i-k]-'0') << (k - 1)
266+
b := int64(s[i] - '0')
267+
x = (x-a)<<1 | b
268+
ss[x] = true
229269
}
230-
for _, v := range vis {
270+
for _, v := range ss {
231271
if !v {
232272
return false
233273
}
@@ -236,6 +276,28 @@ func hasAllCodes(s string, k int) bool {
236276
}
237277
```
238278

279+
#### TypeScript
280+
281+
```ts
282+
function hasAllCodes(s: string, k: number): boolean {
283+
const n = s.length;
284+
const m = 1 << k;
285+
if (n - k + 1 < m) {
286+
return false;
287+
}
288+
let x = +`0b${s.slice(0, k)}`;
289+
const ss = new Set<number>();
290+
ss.add(x);
291+
for (let i = k; i < n; ++i) {
292+
const a = +s[i - k] << (k - 1);
293+
const b = +s[i];
294+
x = ((x - a) << 1) | b;
295+
ss.add(x);
296+
}
297+
return ss.size === m;
298+
}
299+
```
300+
239301
<!-- tabs:end -->
240302

241303
<!-- solution:end -->

0 commit comments

Comments
 (0)