Problem Description
Given a binary string s, count the number of nonempty substrings that have "dominant ones". A substring is said to have dominant ones if the number of ones in it is greater than or equal to the square of the number of zeros in it.
Key Insights
- A substring with zero zeros always qualifies since condition becomes ones ≥ 0.
- For substrings containing k zeros (k ≥ 1), the condition becomes: ones ≥ k². Since substring length = k + ones, the length must be at least k² + k.
- The quadratic growth of k² means for larger k the condition forces the substring length to be long; in many cases, only substrings with very few zeros can satisfy the condition.
- By precomputing the positions of zeros and counting substrings that cover a “block” of exactly k zeros, we can “expand” these minimal blocks to the left and right (but not including an extra zero) and count only those extensions that yield a total length L ≥ k²+k.
- For substrings with no zeros, simply count the contiguous segments of ones.
Space and Time Complexity
Time Complexity: O(n + m * A) where n is the length of s, m is the number of zeros, and A is the average number of left extension choices. In worst-case scenarios (like a dense zeros string) the loops are efficient because most left/right extension counts are small. Space Complexity: O(n) for storing the positions of zeros.
Solution
We solve the problem by splitting it into two parts:
- Count all substrings that contain no zeros (these are substrings from continuous segments of ones).
- Count all substrings that contain exactly k zeros (for 1 ≤ k ≤ m). For each such substring, determine the minimal block that “must” be included (from the first to the last zero in that block). Then, calculate how many ways we can extend to the left and right while staying within the limits (bound by the position of the previous or next zero) so that the overall length L is at least k²+k.
For a block (i, i+k-1) in the zero-index list:
- Left extension: the substring can start anywhere from (prev_zero + 1) to zeros[i] (if i==0, prev_zero is -1).
- Right extension: the substring can end anywhere from zeros[i+k-1] to (next_zero - 1) (if i+k-1 is the last zero then next_zero is n).
- The minimal block length is given by zeros[i+k-1] - zeros[i] + 1.
- To satisfy ones ≥ k², i.e. total length L ≥ k²+k, we need additional extension length R such that (base_length + L_ext + R_ext) ≥ k²+k.
- For each possible left extension length L (from 0 up to left_options-1) we count how many right extension values R (0 to right_options-1) yield L+R ≥ (needed extension) and subtract those invalid pairs from total possibilities.
This method counts each valid substring exactly once without iterating over all O(n²) substrings.