Count the Number of Substrings With Dominant Ones
MedPrompt
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.
| 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.
| 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 <= s.length <= 4 * 104sconsists only of characters'0'and'1'.
Approaches
2 approaches with complexity analysis and trade-offs.
The most straightforward approach is to generate every possible substring of the input string s, and for each substring, check if it satisfies the 'dominant ones' condition. A substring is dominant if the count of '1's is greater than or equal to the square of the count of '0's.
Algorithm
- Initialize a variable
ansto 0 to store the count of dominant substrings. - Use a nested loop to iterate through all possible substrings. The outer loop variable
irepresents the start of the substring, and the inner loop variablejrepresents the end. - For each starting index
i, initialize counts for zeros and ones to 0. - In the inner loop, for each character
s[j], update the counts of zeros and ones for the substrings[i..j]. - Check if the condition
ones >= zeros * zerosis met. - If the condition is true, increment
ans. - After iterating through all substrings, return
ans.
Walkthrough
We can use two nested loops to define all substrings. The outer loop iterates through all possible starting indices i from 0 to n-1, and the inner loop iterates through all possible ending indices j from i to n-1, where n is the length of the string.
For each substring s[i..j], we can maintain a running count of zeros (zeros) and ones (ones). As we extend the substring by moving j from i to n-1, we update these counts. After each update, we check if the condition ones >= zeros * zeros holds. If it does, we increment our total count of dominant substrings.
Here is the algorithm:
- Initialize a counter
ansto 0. - Loop for
ifrom0ton-1: a. Initializezeros = 0andones = 0. b. Loop forjfromiton-1: i. Ifs[j]is '0', incrementzeros. Otherwise, incrementones. ii. Check ifones >= zeros * zeros. iii. If the condition is true, incrementans. - Return
ans.
class Solution { public long countSubstrings(String s) { int n = s.length(); long ans = 0; for (int i = 0; i < n; i++) { int zeros = 0; int ones = 0; for (int j = i; j < n; j++) { if (s.charAt(j) == '0') { zeros++; } else { ones++; } if (ones >= (long)zeros * zeros) { ans++; } } } return ans; }}Complexity
Time
O(N^2), where N is the length of the string `s`. The two nested loops iterate through all possible substrings, which are O(N^2) in number. For each substring, the check is an O(1) operation.
Space
O(1), as we only use a few variables to store the counts and the final answer, regardless of the input string size.
Trade-offs
Pros
Simple to understand and implement.
Cons
Inefficient for large inputs. Given N can be up to 4 * 10^4, N^2 can be up to 1.6 * 10^9, which will lead to a Time Limit Exceeded (TLE) error.
Video walkthrough
Newsletter
One sharp idea, every week
System design and interview prep — short enough to finish.
No spam. Unsubscribe anytime.
Practice
Same difficulty — related problems to reinforce the pattern.