3479 Count The Number Of Substrings With Dominant Ones
3479 Count The Number Of Substrings With Dominant Ones
Count the Number of Substrings With Dominant Ones 
You are given a binary string s.
Return the number of substrings with dominant ones.
A string has dominant ones if the number of ones in the string is greater than or equal to the square of the number of zeros in the string.
Example 1:
Input: s = “00011”
Output: 5
Explanation:
The substrings with dominant ones are shown in the table below.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
i
j
s[i..j]
Number of Zeros
Number of Ones
3
3
1
0
1
4
4
1
0
1
2
3
01
1
1
3
4
11
0
2
2
4
011
1
2
Example 2:
Input: s = “101101”
Output: 16
Explanation:
The substrings with non-dominant ones are shown in the table below.
Since there are 21 substrings total and 5 of them have non-dominant ones, it follows that there are 16 substrings with dominant ones.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
i
j
s[i..j]
Number of Zeros
Number of Ones
1
1
0
1
0
4
4
0
1
0
1
4
0110
2
2
0
4
10110
2
3
1
5
01101
2
3
Constraints:
1
2
1 <= s.length <= 4 * 104
s consists only of characters '0' and '1'.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
impl Solution {
pub fn number_of_substrings(s: String) -> i32 {
// some kind of sliding window
// when you find 1, then count all 1s
// all 1s (with 0 0s) + (all 1s starting from first 1 with 0 0s - 1)+
//all 1s starting from first 1 with 0 0s, with 1 0s,
//101101
//10,11,21,31,32,42 ->
//
//4 + 1 +
// no this does not work
// n2 is easy
// for sliding windw we need to find when should we keep inc
// its not possible right ?
// maybe try to find the non-dominant
// if you see a 0 then
// maybe prefix sum works
// 101101
// 10,11,21,31,32,42 -> 1 and 0s
// let's analyze first what would it take to count equal numbers of 1s and 0s
// we add 1 for each 1 and reduce 1 for each 1
// then two indexes having same number have equale number of 1s and 0s
// GAVE UP
let chars: Vec<char> = s.chars().collect();
let n = chars.len();
let mut pre = vec![-1; n + 1];
for i in 0..n {
if i == 0 || chars[i - 1] == '0' {
pre[i + 1] = i as i32;
} else {
pre[i + 1] = pre[i];
}
}
let mut res = 0i32;
for i in 1..=n {
let mut cnt0 = if chars[i - 1] == '0' { 1 } else { 0 };
let mut j = i as i32;
while j > 0 && (cnt0 * cnt0) as usize <= n {
let cnt1 = (i as i32 - pre[j as usize]) - cnt0;
if cnt0 * cnt0 <= cnt1 {
res += std::cmp::min(j - pre[j as usize], cnt1 - cnt0 * cnt0 + 1);
}
j = pre[j as usize];
cnt0 += 1;
}
}
res
}
}
This post is licensed under CC BY 4.0 by the author.