Skip to content

feat: add solutions to lc problem: No.1461 #3353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,11 @@ tags:

### 方法一:哈希表

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

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

时间复杂度 $O(n \times k)$,空间复杂度 $O(n)$。其中 $n$ 是字符串 $s$ 的长度。

<!-- tabs:start -->

Expand All @@ -79,20 +81,29 @@ tags:
```python
class Solution:
def hasAllCodes(self, s: str, k: int) -> bool:
ss = {s[i : i + k] for i in range(len(s) - k + 1)}
return len(ss) == 1 << k
n = len(s)
m = 1 << k
if n - k + 1 < m:
return False
ss = {s[i : i + k] for i in range(n - k + 1)}
return len(ss) == m
```

#### Java

```java
class Solution {
public boolean hasAllCodes(String s, int k) {
int n = s.length();
int m = 1 << k;
if (n - k + 1 < m) {
return false;
}
Set<String> ss = new HashSet<>();
for (int i = 0; i < s.length() - k + 1; ++i) {
for (int i = 0; i < n - k + 1; ++i) {
ss.add(s.substring(i, i + k));
}
return ss.size() == 1 << k;
return ss.size() == m;
}
}
```
Expand All @@ -103,11 +114,16 @@ class Solution {
class Solution {
public:
bool hasAllCodes(string s, int k) {
int n = s.size();
int m = 1 << k;
if (n - k + 1 < m) {
return false;
}
unordered_set<string> ss;
for (int i = 0; i + k <= s.size(); ++i) {
for (int i = 0; i + k <= n; ++i) {
ss.insert(move(s.substr(i, k)));
}
return ss.size() == 1 << k;
return ss.size() == m;
}
};
```
Expand All @@ -116,11 +132,32 @@ public:

```go
func hasAllCodes(s string, k int) bool {
n, m := len(s), 1<<k
if n-k+1 < m {
return false
}
ss := map[string]bool{}
for i := 0; i+k <= len(s); i++ {
for i := 0; i+k <= n; i++ {
ss[s[i:i+k]] = true
}
return len(ss) == 1<<k
return len(ss) == m
}
```

#### TypeScript

```ts
function hasAllCodes(s: string, k: number): boolean {
const n = s.length;
const m = 1 << k;
if (n - k + 1 < m) {
return false;
}
const ss = new Set<string>();
for (let i = 0; i + k <= n; ++i) {
ss.add(s.slice(i, i + k));
}
return ss.size === m;
}
```

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

### 方法二:滑动窗口

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

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

<!-- tabs:start -->

Expand All @@ -143,17 +180,19 @@ func hasAllCodes(s string, k int) bool {
```python
class Solution:
def hasAllCodes(self, s: str, k: int) -> bool:
if len(s) - k + 1 < (1 << k):
n = len(s)
m = 1 << k
if n - k + 1 < m:
return False
vis = [False] * (1 << k)
num = int(s[:k], 2)
vis[num] = True
for i in range(k, len(s)):
a = (ord(s[i - k]) - ord('0')) << (k - 1)
b = ord(s[i]) - ord('0')
num = ((num - a) << 1) + b
vis[num] = True
return all(v for v in vis)
ss = set()
x = int(s[:k], 2)
ss.add(x)
for i in range(k, n):
a = int(s[i - k]) << (k - 1)
b = int(s[i])
x = (x - a) << 1 | b
ss.add(x)
return len(ss) == m
```

#### Java
Expand All @@ -162,19 +201,20 @@ class Solution:
class Solution {
public boolean hasAllCodes(String s, int k) {
int n = s.length();
if (n - k + 1 < (1 << k)) {
int m = 1 << k;
if (n - k + 1 < m) {
return false;
}
boolean[] vis = new boolean[1 << k];
int num = Integer.parseInt(s.substring(0, k), 2);
vis[num] = true;
boolean[] ss = new boolean[m];
int x = Integer.parseInt(s.substring(0, k), 2);
ss[x] = true;
for (int i = k; i < n; ++i) {
int a = (s.charAt(i - k) - '0') << (k - 1);
int b = s.charAt(i) - '0';
num = (num - a) << 1 | b;
vis[num] = true;
x = (x - a) << 1 | b;
ss[x] = true;
}
for (boolean v : vis) {
for (boolean v : ss) {
if (!v) {
return false;
}
Expand All @@ -191,19 +231,21 @@ class Solution {
public:
bool hasAllCodes(string s, int k) {
int n = s.size();
if (n - k + 1 < (1 << k)) return false;
vector<bool> vis(1 << k);
int num = stoi(s.substr(0, k), nullptr, 2);
vis[num] = true;
int m = 1 << k;
if (n - k + 1 < m) {
return false;
}
bool ss[m];
memset(ss, false, sizeof(ss));
int x = stoi(s.substr(0, k), nullptr, 2);
ss[x] = true;
for (int i = k; i < n; ++i) {
int a = (s[i - k] - '0') << (k - 1);
int b = s[i] - '0';
num = (num - a) << 1 | b;
vis[num] = true;
x = (x - a) << 1 | b;
ss[x] = true;
}
for (bool v : vis)
if (!v) return false;
return true;
return all_of(ss, ss + m, [](bool v) { return v; });
}
};
```
Expand All @@ -212,22 +254,20 @@ public:

```go
func hasAllCodes(s string, k int) bool {
n := len(s)
if n-k+1 < (1 << k) {
n, m := len(s), 1<<k
if n-k+1 < m {
return false
}
vis := make([]bool, 1<<k)
num := 0
for i := 0; i < k; i++ {
num = num<<1 | int(s[i]-'0')
}
vis[num] = true
ss := make([]bool, m)
x, _ := strconv.ParseInt(s[:k], 2, 64)
ss[x] = true
for i := k; i < n; i++ {
a := int(s[i-k]-'0') << (k - 1)
num = (num-a)<<1 | int(s[i]-'0')
vis[num] = true
a := int64(s[i-k]-'0') << (k - 1)
b := int64(s[i] - '0')
x = (x-a)<<1 | b
ss[x] = true
}
for _, v := range vis {
for _, v := range ss {
if !v {
return false
}
Expand All @@ -236,6 +276,28 @@ func hasAllCodes(s string, k int) bool {
}
```

#### TypeScript

```ts
function hasAllCodes(s: string, k: number): boolean {
const n = s.length;
const m = 1 << k;
if (n - k + 1 < m) {
return false;
}
let x = +`0b${s.slice(0, k)}`;
const ss = new Set<number>();
ss.add(x);
for (let i = k; i < n; ++i) {
const a = +s[i - k] << (k - 1);
const b = +s[i];
x = ((x - a) << 1) | b;
ss.add(x);
}
return ss.size === m;
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Loading
Loading