Skip to content
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
6 changes: 3 additions & 3 deletions solution/0900-0999/0908.Smallest Range I/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ tags:

### 方法一:数学

根据题目描述,我们可以将数组中的最大值加上 $k$,最小值减去 $k$,这样可以使得数组中的最大值和最小值之差变小。
根据题目描述,我们可以将数组中的最大值减去 $k$,最小值加上 $k$,这样可以使得数组中的最大值和最小值之差变小。

因此,最终的答案就是 $\max(nums) - \min(nums) - 2 \times k$。
因此,最终的答案就是 $\max(\textit{nums}) - \min(\textit{nums}) - 2 \times k$ 和 $0$ 之间的较大值

时间复杂度 $O(n)$,其中 $n$ 为数组 `nums` 的长度。空间复杂度 $O(1)$。
时间复杂度 $O(n)$,其中 $n$ 为数组 $\textit{nums}$ 的长度。空间复杂度 $O(1)$。

<!-- tabs:start -->

Expand Down
6 changes: 3 additions & 3 deletions solution/0900-0999/0908.Smallest Range I/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ tags:

### Solution 1: Mathematics

According to the problem description, we can add $k$ to the maximum value in the array and subtract $k$ from the minimum value. This can reduce the difference between the maximum and minimum values in the array.
According to the problem description, we can subtract $k$ from the maximum value in the array and add $k$ to the minimum value in the array, which can reduce the difference between the maximum and minimum values in the array.

Therefore, the final answer is $\max(nums) - \min(nums) - 2 \times k$.
Therefore, the final answer is the larger value between $\max(\textit{nums}) - \min(\textit{nums}) - 2 \times k$ and $0$.

The time complexity is $O(n)$, where $n$ is the length of the array `nums`. The space complexity is $O(1)$.
The time complexity is $O(n)$, where $n$ is the length of the array $\textit{nums}$. The space complexity is $O(1)$.

<!-- tabs:start -->

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,32 +67,112 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3325.Co

<!-- solution:start -->

### 方法一
### 方法一:滑动窗口

我们可以枚举子字符串的右端点,然后用一个滑动窗口维护子字符串的左端点,使得滑动窗口内的子字符串中的每个字符出现次数都小于 $k$。

我们可以用一个数组 $\textit{cnt}$ 维护滑动窗口内的每个字符的出现次数,然后用一个变量 $\textit{l}$ 维护滑动窗口的左端点,用一个变量 $\textit{ans}$ 维护答案。

当我们枚举右端点时,我们可以将右端点的字符加入滑动窗口,然后判断滑动窗口内右端点的字符出现次数是否大于等于 $k$,如果是,则将左端点的字符移出滑动窗口,直到滑动窗口内的每个字符出现次数都小于 $k$。此时,对于左端点为 $[0, ..l - 1]$,且右端点为 $r$ 的子字符串,都满足题目要求,因此答案加上 $l$。

枚举结束后,返回答案即可。

时间复杂度 $O(n)$,其中 $n$ 为字符串 $s$ 的长度。空间复杂度 $O(|\Sigma|)$,其中 $\Sigma$ 是字符集,这里是小写字母集合,因此 $|\Sigma| = 26$。

<!-- tabs:start -->

#### Python3

```python

class Solution:
def numberOfSubstrings(self, s: str, k: int) -> int:
cnt = Counter()
ans = l = 0
for c in s:
cnt[c] += 1
while cnt[c] >= k:
cnt[s[l]] -= 1
l += 1
ans += l
return ans
```

#### Java

```java

class Solution {
public int numberOfSubstrings(String s, int k) {
int[] cnt = new int[26];
int ans = 0, l = 0;
for (int r = 0; r < s.length(); ++r) {
int c = s.charAt(r) - 'a';
++cnt[c];
while (cnt[c] >= k) {
--cnt[s.charAt(l) - 'a'];
l++;
}
ans += l;
}
return ans;
}
}
```

#### C++

```cpp

class Solution {
public:
int numberOfSubstrings(string s, int k) {
int n = s.size();
int ans = 0, l = 0;
int cnt[26]{};
for (char& c : s) {
++cnt[c - 'a'];
while (cnt[c - 'a'] >= k) {
--cnt[s[l++] - 'a'];
}
ans += l;
}
return ans;
}
};
```

#### Go

```go
func numberOfSubstrings(s string, k int) (ans int) {
l := 0
cnt := [26]int{}
for _, c := range s {
cnt[c-'a']++
for cnt[c-'a'] >= k {
cnt[s[l]-'a']--
l++
}
ans += l
}
return
}
```

#### TypeScript

```ts
function numberOfSubstrings(s: string, k: number): number {
let [ans, l] = [0, 0];
const cnt: number[] = Array(26).fill(0);
for (const c of s) {
const x = c.charCodeAt(0) - 'a'.charCodeAt(0);
++cnt[x];
while (cnt[x] >= k) {
--cnt[s[l++].charCodeAt(0) - 'a'.charCodeAt(0)];
}
ans += l;
}
return ans;
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,32 +65,112 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3325.Co

<!-- solution:start -->

### Solution 1
### Solution 1: Sliding Window

We can enumerate the right endpoint of the substring, and then use a sliding window to maintain the left endpoint of the substring, ensuring that the occurrence count of each character in the sliding window is less than $k$.

We can use an array $\textit{cnt}$ to maintain the occurrence count of each character in the sliding window, then use a variable $\textit{l}$ to maintain the left endpoint of the sliding window, and use a variable $\textit{ans}$ to maintain the answer.

When we enumerate the right endpoint, we can add the character at the right endpoint to the sliding window, then check if the occurrence count of the character at the right endpoint in the sliding window is greater than or equal to $k$. If it is, we remove the character at the left endpoint from the sliding window until the occurrence count of each character in the sliding window is less than $k$. At this point, for substrings with left endpoints in the range $[0, ..l - 1]$ and right endpoint $r$, all satisfy the problem's requirements, so we add $l$ to the answer.

After enumeration, we return the answer.

The time complexity is $O(n)$, where $n$ is the length of the string $s$. The space complexity is $O(|\Sigma|)$, where $\Sigma$ is the character set, which in this case is the set of lowercase letters, so $|\Sigma| = 26$.

<!-- tabs:start -->

#### Python3

```python

class Solution:
def numberOfSubstrings(self, s: str, k: int) -> int:
cnt = Counter()
ans = l = 0
for c in s:
cnt[c] += 1
while cnt[c] >= k:
cnt[s[l]] -= 1
l += 1
ans += l
return ans
```

#### Java

```java

class Solution {
public int numberOfSubstrings(String s, int k) {
int[] cnt = new int[26];
int ans = 0, l = 0;
for (int r = 0; r < s.length(); ++r) {
int c = s.charAt(r) - 'a';
++cnt[c];
while (cnt[c] >= k) {
--cnt[s.charAt(l) - 'a'];
l++;
}
ans += l;
}
return ans;
}
}
```

#### C++

```cpp

class Solution {
public:
int numberOfSubstrings(string s, int k) {
int n = s.size();
int ans = 0, l = 0;
int cnt[26]{};
for (char& c : s) {
++cnt[c - 'a'];
while (cnt[c - 'a'] >= k) {
--cnt[s[l++] - 'a'];
}
ans += l;
}
return ans;
}
};
```

#### Go

```go
func numberOfSubstrings(s string, k int) (ans int) {
l := 0
cnt := [26]int{}
for _, c := range s {
cnt[c-'a']++
for cnt[c-'a'] >= k {
cnt[s[l]-'a']--
l++
}
ans += l
}
return
}
```

#### TypeScript

```ts
function numberOfSubstrings(s: string, k: number): number {
let [ans, l] = [0, 0];
const cnt: number[] = Array(26).fill(0);
for (const c of s) {
const x = c.charCodeAt(0) - 'a'.charCodeAt(0);
++cnt[x];
while (cnt[x] >= k) {
--cnt[s[l++].charCodeAt(0) - 'a'.charCodeAt(0)];
}
ans += l;
}
return ans;
}
```

<!-- tabs:end -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution {
public:
int numberOfSubstrings(string s, int k) {
int n = s.size();
int ans = 0, l = 0;
int cnt[26]{};
for (char& c : s) {
++cnt[c - 'a'];
while (cnt[c - 'a'] >= k) {
--cnt[s[l++] - 'a'];
}
ans += l;
}
return ans;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
func numberOfSubstrings(s string, k int) (ans int) {
l := 0
cnt := [26]int{}
for _, c := range s {
cnt[c-'a']++
for cnt[c-'a'] >= k {
cnt[s[l]-'a']--
l++
}
ans += l
}
return
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Solution {
public int numberOfSubstrings(String s, int k) {
int[] cnt = new int[26];
int ans = 0, l = 0;
for (int r = 0; r < s.length(); ++r) {
int c = s.charAt(r) - 'a';
++cnt[c];
while (cnt[c] >= k) {
--cnt[s.charAt(l) - 'a'];
l++;
}
ans += l;
}
return ans;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Solution:
def numberOfSubstrings(self, s: str, k: int) -> int:
cnt = Counter()
ans = l = 0
for c in s:
cnt[c] += 1
while cnt[c] >= k:
cnt[s[l]] -= 1
l += 1
ans += l
return ans
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
function numberOfSubstrings(s: string, k: number): number {
let [ans, l] = [0, 0];
const cnt: number[] = Array(26).fill(0);
for (const c of s) {
const x = c.charCodeAt(0) - 'a'.charCodeAt(0);
++cnt[x];
while (cnt[x] >= k) {
--cnt[s[l++].charCodeAt(0) - 'a'.charCodeAt(0)];
}
ans += l;
}
return ans;
}
Loading