Skip to content

Commit e980e6c

Browse files
authored
feat: add solutions to lc problem: No.3234 (#4825)
1 parent 7017b80 commit e980e6c

File tree

7 files changed

+411
-8
lines changed

7 files changed

+411
-8
lines changed

solution/3200-3299/3234.Count the Number of Substrings With Dominant Ones/README.md

Lines changed: 142 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -167,32 +167,170 @@ tags:
167167

168168
<!-- solution:start -->
169169

170-
### 方法一
170+
### 方法一:预处理 + 枚举
171+
172+
根据题目描述,显著字符串满足 $\textit{cnt}_1 \geq \textit{cnt}_0^2$,那么 $\textit{cnt}_0$ 的最大值不超过 $\sqrt{n}$,其中 $n$ 是字符串的长度。因此我们可以枚举 $\textit{cnt}_0$ 的值,然后计算满足条件的子字符串数量。
173+
174+
我们首先预处理字符串中每个位置开始的第一个 $0$ 的位置,存储在数组 $\textit{nxt}$ 中,其中 $\textit{nxt}[i]$ 表示从位置 $i$ 开始的第一个 $0$ 的位置,如果不存在则为 $n$。
175+
176+
接下来,我们遍历字符串的每个位置 $i$ 作为子字符串的起始位置,初始化 $\textit{cnt}_0$ 的值为 $0$ 或 $1$(取决于当前位置是否为 $0$)。然后我们使用一个指针 $j$ 从位置 $i$ 开始,逐步跳转到下一个 $0$ 的位置,同时更新 $\textit{cnt}_0$ 的值。
177+
178+
对于从位置 $i$ 开始,且包含 $\textit{cnt}_0$ 个 $0$ 的子字符串,最多可以包含 $\textit{nxt}[j + 1] - i - \textit{cnt}_0$ 个 $1$。如果这个数量大于等于 $\textit{cnt}_0^2$,则说明存在满足条件的子字符串。此时需要判断字符串从右端点 $\textit{nxt}[j + 1] - 1$ 向左移动多少个位置,可以使得子字符串仍然满足条件。具体来说,右端点一共可以有 $\min(\textit{nxt}[j + 1] - j, \textit{cnt}_1 - \textit{cnt}_0^2 + 1)$ 种选择方式。我们将这些数量累加到答案中。然后将指针 $j$ 移动到下一个 $0$ 的位置,继续枚举下一个 $\textit{cnt}_0$ 的值,直到 $\textit{cnt}_0^2$ 超过字符串长度为止。
179+
180+
时间复杂度 $O(n \times \sqrt{n})$,空间复杂度 $O(n)$,其中 $n$ 是字符串的长度。
171181

172182
<!-- tabs:start -->
173183

174184
#### Python3
175185

176186
```python
177-
187+
class Solution:
188+
def numberOfSubstrings(self, s: str) -> int:
189+
n = len(s)
190+
nxt = [n] * (n + 1)
191+
for i in range(n - 1, -1, -1):
192+
nxt[i] = nxt[i + 1]
193+
if s[i] == "0":
194+
nxt[i] = i
195+
ans = 0
196+
for i in range(n):
197+
cnt0 = int(s[i] == "0")
198+
j = i
199+
while j < n and cnt0 * cnt0 <= n:
200+
cnt1 = (nxt[j + 1] - i) - cnt0
201+
if cnt1 >= cnt0 * cnt0:
202+
ans += min(nxt[j + 1] - j, cnt1 - cnt0 * cnt0 + 1)
203+
j = nxt[j + 1]
204+
cnt0 += 1
205+
return ans
178206
```
179207

180208
#### Java
181209

182210
```java
183-
211+
class Solution {
212+
public int numberOfSubstrings(String s) {
213+
int n = s.length();
214+
int[] nxt = new int[n + 1];
215+
nxt[n] = n;
216+
for (int i = n - 1; i >= 0; --i) {
217+
nxt[i] = nxt[i + 1];
218+
if (s.charAt(i) == '0') {
219+
nxt[i] = i;
220+
}
221+
}
222+
int ans = 0;
223+
for (int i = 0; i < n; ++i) {
224+
int cnt0 = s.charAt(i) == '0' ? 1 : 0;
225+
int j = i;
226+
while (j < n && 1L * cnt0 * cnt0 <= n) {
227+
int cnt1 = nxt[j + 1] - i - cnt0;
228+
if (cnt1 >= cnt0 * cnt0) {
229+
ans += Math.min(nxt[j + 1] - j, cnt1 - cnt0 * cnt0 + 1);
230+
}
231+
j = nxt[j + 1];
232+
++cnt0;
233+
}
234+
}
235+
return ans;
236+
}
237+
}
184238
```
185239

186240
#### C++
187241

188242
```cpp
189-
243+
class Solution {
244+
public:
245+
int numberOfSubstrings(string s) {
246+
int n = s.size();
247+
vector<int> nxt(n + 1);
248+
nxt[n] = n;
249+
for (int i = n - 1; i >= 0; --i) {
250+
nxt[i] = nxt[i + 1];
251+
if (s[i] == '0') {
252+
nxt[i] = i;
253+
}
254+
}
255+
int ans = 0;
256+
for (int i = 0; i < n; ++i) {
257+
int cnt0 = s[i] == '0' ? 1 : 0;
258+
int j = i;
259+
while (j < n && 1LL * cnt0 * cnt0 <= n) {
260+
int cnt1 = nxt[j + 1] - i - cnt0;
261+
if (cnt1 >= cnt0 * cnt0) {
262+
ans += min(nxt[j + 1] - j, cnt1 - cnt0 * cnt0 + 1);
263+
}
264+
j = nxt[j + 1];
265+
++cnt0;
266+
}
267+
}
268+
return ans;
269+
}
270+
};
190271
```
191272
192273
#### Go
193274
194275
```go
276+
func numberOfSubstrings(s string) int {
277+
n := len(s)
278+
nxt := make([]int, n+1)
279+
nxt[n] = n
280+
for i := n - 1; i >= 0; i-- {
281+
nxt[i] = nxt[i+1]
282+
if s[i] == '0' {
283+
nxt[i] = i
284+
}
285+
}
286+
ans := 0
287+
for i := 0; i < n; i++ {
288+
cnt0 := 0
289+
if s[i] == '0' {
290+
cnt0 = 1
291+
}
292+
j := i
293+
for j < n && int64(cnt0*cnt0) <= int64(n) {
294+
cnt1 := nxt[j+1] - i - cnt0
295+
if cnt1 >= cnt0*cnt0 {
296+
ans += min(nxt[j+1]-j, cnt1-cnt0*cnt0+1)
297+
}
298+
j = nxt[j+1]
299+
cnt0++
300+
}
301+
}
302+
return ans
303+
}
304+
```
195305

306+
#### TypeScript
307+
308+
```ts
309+
function numberOfSubstrings(s: string): number {
310+
const n = s.length;
311+
const nxt: number[] = Array(n + 1).fill(0);
312+
nxt[n] = n;
313+
for (let i = n - 1; i >= 0; --i) {
314+
nxt[i] = nxt[i + 1];
315+
if (s[i] === '0') {
316+
nxt[i] = i;
317+
}
318+
}
319+
let ans = 0;
320+
for (let i = 0; i < n; ++i) {
321+
let cnt0 = s[i] === '0' ? 1 : 0;
322+
let j = i;
323+
while (j < n && cnt0 * cnt0 <= n) {
324+
const cnt1 = nxt[j + 1] - i - cnt0;
325+
if (cnt1 >= cnt0 * cnt0) {
326+
ans += Math.min(nxt[j + 1] - j, cnt1 - cnt0 * cnt0 + 1);
327+
}
328+
j = nxt[j + 1];
329+
++cnt0;
330+
}
331+
}
332+
return ans;
333+
}
196334
```
197335

198336
<!-- tabs:end -->

solution/3200-3299/3234.Count the Number of Substrings With Dominant Ones/README_EN.md

Lines changed: 142 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,32 +165,170 @@ tags:
165165

166166
<!-- solution:start -->
167167

168-
### Solution 1
168+
### Solution 1: Preprocessing + Enumeration
169+
170+
According to the problem description, a dominant string satisfies $\textit{cnt}_1 \geq \textit{cnt}_0^2$, which means the maximum value of $\textit{cnt}_0$ does not exceed $\sqrt{n}$, where $n$ is the length of the string. Therefore, we can enumerate the value of $\textit{cnt}_0$ and then calculate the number of substrings that satisfy the condition.
171+
172+
We first preprocess the position of the first $0$ starting from each position in the string, storing it in the array $\textit{nxt}$, where $\textit{nxt}[i]$ represents the position of the first $0$ starting from position $i$, or $n$ if it doesn't exist.
173+
174+
Next, we iterate through each position $i$ in the string as the starting position of the substring, initializing $\textit{cnt}_0$ to $0$ or $1$ (depending on whether the current position is $0$). Then we use a pointer $j$ starting from position $i$, jumping step by step to the position of the next $0$, while updating the value of $\textit{cnt}_0$.
175+
176+
For a substring starting at position $i$ and containing $\textit{cnt}_0$ zeros, it can contain at most $\textit{nxt}[j + 1] - i - \textit{cnt}_0$ ones. If this quantity is greater than or equal to $\textit{cnt}_0^2$, it means there exists a substring that satisfies the condition. At this point, we need to determine how many positions the right endpoint $\textit{nxt}[j + 1] - 1$ can move left while still satisfying the condition. Specifically, the right endpoint has a total of $\min(\textit{nxt}[j + 1] - j, \textit{cnt}_1 - \textit{cnt}_0^2 + 1)$ possible choices. We accumulate these counts to the answer. Then we move pointer $j$ to the position of the next $0$ and continue enumerating the next value of $\textit{cnt}_0$ until $\textit{cnt}_0^2$ exceeds the string length.
177+
178+
The time complexity is $O(n \times \sqrt{n})$, and the space complexity is $O(n)$, where $n$ is the length of the string.
169179

170180
<!-- tabs:start -->
171181

172182
#### Python3
173183

174184
```python
175-
185+
class Solution:
186+
def numberOfSubstrings(self, s: str) -> int:
187+
n = len(s)
188+
nxt = [n] * (n + 1)
189+
for i in range(n - 1, -1, -1):
190+
nxt[i] = nxt[i + 1]
191+
if s[i] == "0":
192+
nxt[i] = i
193+
ans = 0
194+
for i in range(n):
195+
cnt0 = int(s[i] == "0")
196+
j = i
197+
while j < n and cnt0 * cnt0 <= n:
198+
cnt1 = (nxt[j + 1] - i) - cnt0
199+
if cnt1 >= cnt0 * cnt0:
200+
ans += min(nxt[j + 1] - j, cnt1 - cnt0 * cnt0 + 1)
201+
j = nxt[j + 1]
202+
cnt0 += 1
203+
return ans
176204
```
177205

178206
#### Java
179207

180208
```java
181-
209+
class Solution {
210+
public int numberOfSubstrings(String s) {
211+
int n = s.length();
212+
int[] nxt = new int[n + 1];
213+
nxt[n] = n;
214+
for (int i = n - 1; i >= 0; --i) {
215+
nxt[i] = nxt[i + 1];
216+
if (s.charAt(i) == '0') {
217+
nxt[i] = i;
218+
}
219+
}
220+
int ans = 0;
221+
for (int i = 0; i < n; ++i) {
222+
int cnt0 = s.charAt(i) == '0' ? 1 : 0;
223+
int j = i;
224+
while (j < n && 1L * cnt0 * cnt0 <= n) {
225+
int cnt1 = nxt[j + 1] - i - cnt0;
226+
if (cnt1 >= cnt0 * cnt0) {
227+
ans += Math.min(nxt[j + 1] - j, cnt1 - cnt0 * cnt0 + 1);
228+
}
229+
j = nxt[j + 1];
230+
++cnt0;
231+
}
232+
}
233+
return ans;
234+
}
235+
}
182236
```
183237

184238
#### C++
185239

186240
```cpp
187-
241+
class Solution {
242+
public:
243+
int numberOfSubstrings(string s) {
244+
int n = s.size();
245+
vector<int> nxt(n + 1);
246+
nxt[n] = n;
247+
for (int i = n - 1; i >= 0; --i) {
248+
nxt[i] = nxt[i + 1];
249+
if (s[i] == '0') {
250+
nxt[i] = i;
251+
}
252+
}
253+
int ans = 0;
254+
for (int i = 0; i < n; ++i) {
255+
int cnt0 = s[i] == '0' ? 1 : 0;
256+
int j = i;
257+
while (j < n && 1LL * cnt0 * cnt0 <= n) {
258+
int cnt1 = nxt[j + 1] - i - cnt0;
259+
if (cnt1 >= cnt0 * cnt0) {
260+
ans += min(nxt[j + 1] - j, cnt1 - cnt0 * cnt0 + 1);
261+
}
262+
j = nxt[j + 1];
263+
++cnt0;
264+
}
265+
}
266+
return ans;
267+
}
268+
};
188269
```
189270
190271
#### Go
191272
192273
```go
274+
func numberOfSubstrings(s string) int {
275+
n := len(s)
276+
nxt := make([]int, n+1)
277+
nxt[n] = n
278+
for i := n - 1; i >= 0; i-- {
279+
nxt[i] = nxt[i+1]
280+
if s[i] == '0' {
281+
nxt[i] = i
282+
}
283+
}
284+
ans := 0
285+
for i := 0; i < n; i++ {
286+
cnt0 := 0
287+
if s[i] == '0' {
288+
cnt0 = 1
289+
}
290+
j := i
291+
for j < n && int64(cnt0*cnt0) <= int64(n) {
292+
cnt1 := nxt[j+1] - i - cnt0
293+
if cnt1 >= cnt0*cnt0 {
294+
ans += min(nxt[j+1]-j, cnt1-cnt0*cnt0+1)
295+
}
296+
j = nxt[j+1]
297+
cnt0++
298+
}
299+
}
300+
return ans
301+
}
302+
```
193303

304+
#### TypeScript
305+
306+
```ts
307+
function numberOfSubstrings(s: string): number {
308+
const n = s.length;
309+
const nxt: number[] = Array(n + 1).fill(0);
310+
nxt[n] = n;
311+
for (let i = n - 1; i >= 0; --i) {
312+
nxt[i] = nxt[i + 1];
313+
if (s[i] === '0') {
314+
nxt[i] = i;
315+
}
316+
}
317+
let ans = 0;
318+
for (let i = 0; i < n; ++i) {
319+
let cnt0 = s[i] === '0' ? 1 : 0;
320+
let j = i;
321+
while (j < n && cnt0 * cnt0 <= n) {
322+
const cnt1 = nxt[j + 1] - i - cnt0;
323+
if (cnt1 >= cnt0 * cnt0) {
324+
ans += Math.min(nxt[j + 1] - j, cnt1 - cnt0 * cnt0 + 1);
325+
}
326+
j = nxt[j + 1];
327+
++cnt0;
328+
}
329+
}
330+
return ans;
331+
}
194332
```
195333

196334
<!-- tabs:end -->
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class Solution {
2+
public:
3+
int numberOfSubstrings(string s) {
4+
int n = s.size();
5+
vector<int> nxt(n + 1);
6+
nxt[n] = n;
7+
for (int i = n - 1; i >= 0; --i) {
8+
nxt[i] = nxt[i + 1];
9+
if (s[i] == '0') {
10+
nxt[i] = i;
11+
}
12+
}
13+
int ans = 0;
14+
for (int i = 0; i < n; ++i) {
15+
int cnt0 = s[i] == '0' ? 1 : 0;
16+
int j = i;
17+
while (j < n && 1LL * cnt0 * cnt0 <= n) {
18+
int cnt1 = nxt[j + 1] - i - cnt0;
19+
if (cnt1 >= cnt0 * cnt0) {
20+
ans += min(nxt[j + 1] - j, cnt1 - cnt0 * cnt0 + 1);
21+
}
22+
j = nxt[j + 1];
23+
++cnt0;
24+
}
25+
}
26+
return ans;
27+
}
28+
};

0 commit comments

Comments
 (0)