Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2e04c0f

Browse files
feat: add solutions to lc problem: No.3261 (doocs#3717)
No.3261.Count Substrings That Satisfy K-Constraint II
1 parent e315eae commit 2e04c0f

File tree

21 files changed

+458
-30
lines changed

21 files changed

+458
-30
lines changed

‎lcof2/剑指 Offer II 119. 最长连续序列/README.md‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,11 @@ class Solution {
230230
if n < 2 {
231231
return n
232232
}
233-
233+
234234
let sortedNums = Array(Set(nums)).sorted()
235235
var ans = 1
236236
var currentStreak = 1
237-
237+
238238
for i in 1..<sortedNums.count {
239239
if sortedNums[i] == sortedNums[i - 1] + 1 {
240240
currentStreak += 1
@@ -243,7 +243,7 @@ class Solution {
243243
currentStreak = 1
244244
}
245245
}
246-
246+
247247
return ans
248248
}
249249
}
@@ -395,21 +395,21 @@ class Solution {
395395
func longestConsecutive(_ nums: [Int]) -> Int {
396396
let numSet: Set<Int> = Set(nums)
397397
var longestStreak = 0
398-
398+
399399
for num in nums {
400400
if !numSet.contains(num - 1) {
401401
var currentNum = num
402402
var currentStreak = 1
403-
403+
404404
while numSet.contains(currentNum + 1) {
405405
currentNum += 1
406406
currentStreak += 1
407407
}
408-
408+
409409
longestStreak = max(longestStreak, currentStreak)
410410
}
411411
}
412-
412+
413413
return longestStreak
414414
}
415415
}

‎solution/3200-3299/3258.Count Substrings That Satisfy K-Constraint I/README.md‎

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

8989
我们用两个变量 $\textit{cnt0}$ 和 $\textit{cnt1}$ 分别记录当前窗口内的 0ドル$ 和 1ドル$ 的个数,用 $\textit{ans}$ 记录满足 $k$ 约束的子字符串的个数,用 $l$ 记录窗口的左边界。
9090

91-
当我们右移窗口时,如果窗口内的 0ドル$ 和 1ドル$ 的个数都大于 $k,ドル我们就需要左移窗口,直到窗口内的 0ドル$ 和 1ドル$ 的个数都不大于 $k$。此时,窗口内的所有子字符串都满足 $k$ 约束,个数为 $r - l + 1,ドル其中 $r$ 是窗口的右边界。我们将这个个数累加到 $\textit{ans}$ 中。
91+
当我们右移窗口时,如果窗口内的 0ドル$ 和 1ドル$ 的个数都大于 $k,ドル我们就需要左移窗口,直到窗口内的 0ドル$ 和 1ドル$ 的个数都不大于 $k$。此时,窗口内所有以 $r$ 作为右端点的子字符串都满足 $k$ 约束,个数为 $r - l + 1,ドル其中 $r$ 是窗口的右边界。我们将这个个数累加到 $\textit{ans}$ 中。
9292

9393
最后,我们返回 $\textit{ans}$ 即可。
9494

@@ -175,9 +175,9 @@ function countKConstraintSubstrings(s: string, k: number): number {
175175
const cnt: [number, number] = [0, 0];
176176
let [ans, l] = [0, 0];
177177
for (let r = 0; r < s.length; ++r) {
178-
cnt[s.charCodeAt(r) -48]++;
178+
cnt[+s[r]]++;
179179
while (cnt[0] > k && cnt[1] > k) {
180-
cnt[s.charCodeAt(l++) -48]--;
180+
cnt[+s[l++]]--;
181181
}
182182
ans += r - l + 1;
183183
}

‎solution/3200-3299/3258.Count Substrings That Satisfy K-Constraint I/README_EN.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,9 @@ function countKConstraintSubstrings(s: string, k: number): number {
173173
const cnt: [number, number] = [0, 0];
174174
let [ans, l] = [0, 0];
175175
for (let r = 0; r < s.length; ++r) {
176-
cnt[s.charCodeAt(r) -48]++;
176+
cnt[+s[r]]++;
177177
while (cnt[0] > k && cnt[1] > k) {
178-
cnt[s.charCodeAt(l++) -48]--;
178+
cnt[+s[l++]]--;
179179
}
180180
ans += r - l + 1;
181181
}

‎solution/3200-3299/3258.Count Substrings That Satisfy K-Constraint I/Solution.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ function countKConstraintSubstrings(s: string, k: number): number {
22
const cnt: [number, number] = [0, 0];
33
let [ans, l] = [0, 0];
44
for (let r = 0; r < s.length; ++r) {
5-
cnt[s.charCodeAt(r)-48]++;
5+
cnt[+s[r]]++;
66
while (cnt[0] > k && cnt[1] > k) {
7-
cnt[s.charCodeAt(l++)-48]--;
7+
cnt[+s[l++]]--;
88
}
99
ans += r - l + 1;
1010
}

‎solution/3200-3299/3261.Count Substrings That Satisfy K-Constraint II/README.md‎

Lines changed: 137 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,32 +81,165 @@ tags:
8181

8282
<!-- solution:start -->
8383

84-
### 方法一
84+
### 方法一:滑动窗口 + 前缀和
85+
86+
我们用两个变量 $\textit{cnt0}$ 和 $\textit{cnt1}$ 分别记录当前窗口内的 0ドル$ 和 1ドル$ 的个数,指针 $i$ 和 $j$ 分别标识窗口的左右边界。用一个数组 $d$ 记录每个位置 $i$ 右边第一个不满足 $k$ 约束的位置,初始时 $d[i] = n$。另外,用一个长度为 $n + 1$ 的前缀和数组 $\textit{pre}[i]$ 记录以前 $i$ 个位置作为右边界的满足 $k$ 约束的子字符串的个数。
87+
88+
当我们右移窗口时,如果窗口内的 0ドル$ 和 1ドル$ 的个数都大于 $k,ドル我们将 $d[i]$ 更新为 $j,ドル表示位置 $i$ 右边第一个不满足 $k$ 约束的位置。然后我们将 $i$ 右移一位,直到窗口内的 0ドル$ 和 1ドル$ 的个数都不大于 $k$。此时,我们可以计算出以 $j$ 为右边界的满足 $k$ 约束的子字符串的个数,即 $j - i + 1,ドル我们更新到前缀和数组中。
89+
90+
最后,对于每个查询 $[l, r],ドル我们首先找出 $l$ 右边第一个不满足 $k$ 约束的位置 $p,ドル那么 $p = \min(r + 1, d[l]),ドル那么 $[l, p - 1]$ 的所有子字符串都满足 $k$ 约束,个数为 $(1 + p - l) \times (p - l) / 2,ドル然后,我们计算以 $[p, r]$ 为右边界的满足 $k$ 约束的子字符串的个数,即 $\textit{pre}[r + 1] - \textit{pre}[p],ドル最后将两者相加即可。
91+
92+
时间复杂度 $O(n + m),ドル空间复杂度 $O(n)$。其中 $n$ 和 $m$ 分别为字符串 $s$ 的长度和查询数组 $\textit{queries}$ 的长度。
8593

8694
<!-- tabs:start -->
8795

8896
#### Python3
8997

9098
```python
91-
99+
class Solution:
100+
def countKConstraintSubstrings(
101+
self, s: str, k: int, queries: List[List[int]]
102+
) -> List[int]:
103+
cnt = [0, 0]
104+
i, n = 0, len(s)
105+
d = [n] * n
106+
pre = [0] * (n + 1)
107+
for j, x in enumerate(map(int, s)):
108+
cnt[x] += 1
109+
while cnt[0] > k and cnt[1] > k:
110+
d[i] = j
111+
cnt[int(s[i])] -= 1
112+
i += 1
113+
pre[j + 1] = pre[j] + j - i + 1
114+
ans = []
115+
for l, r in queries:
116+
p = min(r + 1, d[l])
117+
a = (1 + p - l) * (p - l) // 2
118+
b = pre[r + 1] - pre[p]
119+
ans.append(a + b)
120+
return ans
92121
```
93122

94123
#### Java
95124

96125
```java
97-
126+
class Solution {
127+
public long[] countKConstraintSubstrings(String s, int k, int[][] queries) {
128+
int[] cnt = new int[2];
129+
int n = s.length();
130+
int[] d = new int[n];
131+
Arrays.fill(d, n);
132+
long[] pre = new long[n + 1];
133+
for (int i = 0, j = 0; j < n; ++j) {
134+
cnt[s.charAt(j) - '0']++;
135+
while (cnt[0] > k && cnt[1] > k) {
136+
d[i] = j;
137+
cnt[s.charAt(i++) - '0']--;
138+
}
139+
pre[j + 1] = pre[j] + j - i + 1;
140+
}
141+
int m = queries.length;
142+
long[] ans = new long[m];
143+
for (int i = 0; i < m; ++i) {
144+
int l = queries[i][0], r = queries[i][1];
145+
int p = Math.min(r + 1, d[l]);
146+
long a = (1L + p - l) * (p - l) / 2;
147+
long b = pre[r + 1] - pre[p];
148+
ans[i] = a + b;
149+
}
150+
return ans;
151+
}
152+
}
98153
```
99154

100155
#### C++
101156

102157
```cpp
103-
158+
class Solution {
159+
public:
160+
vector<long long> countKConstraintSubstrings(string s, int k, vector<vector<int>>& queries) {
161+
int cnt[2]{};
162+
int n = s.size();
163+
vector<int> d(n, n);
164+
long long pre[n + 1];
165+
pre[0] = 0;
166+
for (int i = 0, j = 0; j < n; ++j) {
167+
cnt[s[j] - '0']++;
168+
while (cnt[0] > k && cnt[1] > k) {
169+
d[i] = j;
170+
cnt[s[i++] - '0']--;
171+
}
172+
pre[j + 1] = pre[j] + j - i + 1;
173+
}
174+
vector<long long> ans;
175+
for (const auto& q : queries) {
176+
int l = q[0], r = q[1];
177+
int p = min(r + 1, d[l]);
178+
long long a = (1LL + p - l) * (p - l) / 2;
179+
long long b = pre[r + 1] - pre[p];
180+
ans.push_back(a + b);
181+
}
182+
return ans;
183+
}
184+
};
104185
```
105186
106187
#### Go
107188
108189
```go
190+
func countKConstraintSubstrings(s string, k int, queries [][]int) (ans []int64) {
191+
cnt := [2]int{}
192+
n := len(s)
193+
d := make([]int, n)
194+
for i := range d {
195+
d[i] = n
196+
}
197+
pre := make([]int, n+1)
198+
for i, j := 0, 0; j < n; j++ {
199+
cnt[s[j]-'0']++
200+
for cnt[0] > k && cnt[1] > k {
201+
d[i] = j
202+
cnt[s[i]-'0']--
203+
i++
204+
}
205+
pre[j+1] = pre[j] + j - i + 1
206+
}
207+
for _, q := range queries {
208+
l, r := q[0], q[1]
209+
p := min(r+1, d[l])
210+
a := (1 + p - l) * (p - l) / 2
211+
b := pre[r+1] - pre[p]
212+
ans = append(ans, int64(a+b))
213+
}
214+
return
215+
}
216+
```
109217

218+
#### TypeScript
219+
220+
```ts
221+
function countKConstraintSubstrings(s: string, k: number, queries: number[][]): number[] {
222+
const cnt: [number, number] = [0, 0];
223+
const n = s.length;
224+
const d: number[] = Array(n).fill(n);
225+
const pre: number[] = Array(n + 1).fill(0);
226+
for (let i = 0, j = 0; j < n; ++j) {
227+
cnt[+s[j]]++;
228+
while (Math.min(cnt[0], cnt[1]) > k) {
229+
d[i] = j;
230+
cnt[+s[i++]]--;
231+
}
232+
pre[j + 1] = pre[j] + j - i + 1;
233+
}
234+
const ans: number[] = [];
235+
for (const [l, r] of queries) {
236+
const p = Math.min(r + 1, d[l]);
237+
const a = ((1 + p - l) * (p - l)) / 2;
238+
const b = pre[r + 1] - pre[p];
239+
ans.push(a + b);
240+
}
241+
return ans;
242+
}
110243
```
111244

112245
<!-- tabs:end -->

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /