Number of Good Binary Strings - Solution & Explanation
Problem Statement
You are given four integers minLength, maxLength, oneGroup and zeroGroup.
A binary string is good if it satisfies the following conditions:
- The length of the string is in the range
[minLength, maxLength]. - The size of each block of consecutive
1's is a multiple ofoneGroup.- For example in a binary string
00110111100sizes of each block of consecutive ones are[2,4].
- For example in a binary string
- The size of each block of consecutive
0's is a multiple ofzeroGroup.- For example, in a binary string
00110111100sizes of each block of consecutive zeros are[2,1,2].
- For example, in a binary string
Return the number of good binary strings. Since the answer may be too large, return it modulo 109 + 7.
Note that 0 is considered a multiple of all the numbers.
Example 1:
Input: minLength = 2, maxLength = 3, oneGroup = 1, zeroGroup = 2 Output: 5 Explanation: There are 5 good binary strings in this example: "00", "11", "001", "100", and "111". It can be proven that there are only 5 good strings satisfying all conditions.
Example 2:
Input: minLength = 4, maxLength = 4, oneGroup = 4, zeroGroup = 3 Output: 1 Explanation: There is only 1 good binary string in this example: "1111". It can be proven that there is only 1 good string satisfying all conditions.
Constraints:
1 <= minLength <= maxLength <= 1051 <= oneGroup, zeroGroup <= maxLength
Approach Overview
Problem Overview: You need to count how many binary strings have a length between low and high. The string can only be built by repeatedly appending a block of zero zeros or a block of one ones. The result can grow very large, so return the count modulo 1e9 + 7.
Approach 1: Recursion with Memoization (Top-Down DP) (Time: O(high), Space: O(high))
Think of the problem as building the string length step by step. From a current length len, you can move to len + zero or len + one. A recursive function explores these possibilities until the length exceeds high. Memoization stores the result for each length so repeated states are not recomputed. The key insight is that the number of valid strings depends only on the current length, not on the actual characters used. This turns the recursion tree into a linear number of states.
Approach 2: Bottom-Up Dynamic Programming (Time: O(high), Space: O(high))
Create a DP array where dp[i] represents the number of ways to build a string of length i. Initialize dp[0] = 1 since there is one way to build an empty string. Iterate from length 1 to high, and update dp[i] using previous states: add dp[i - zero] if i >= zero and add dp[i - one] if i >= one. Whenever i falls between low and high, include dp[i] in the final answer. This approach avoids recursion and directly builds the solution using dynamic programming.
Approach 3: Space-Optimized DP Counting (Time: O(high), Space: O(high))
The transition only depends on earlier lengths, so the DP can be computed sequentially without storing additional structures. Maintain a single array up to high and accumulate results during iteration. The algorithm still uses the same recurrence but focuses on minimizing overhead and improving clarity. The logic resembles counting paths in a graph where nodes represent lengths and edges represent valid extensions.
Recommended for interviews: The bottom-up DP solution is what interviewers expect. It clearly shows that you recognized the recurrence relation and implemented an efficient state transition. Explaining the recursive formulation first demonstrates understanding of the state space, while converting it to an iterative dynamic programming solution shows practical problem-solving skill. Problems like this often appear alongside other state-transition questions involving memoization and counting paths.
Solution
We define f[i] as the number of strings of length i that meet the condition. The state transition equation is:
$
f[i] = \begin{cases}
1 & i = 0 \
f[i - oneGroup] + f[i - zeroGroup] & i geq 1
\end{cases}
The final answer is f[minLength] + f[minLength + 1] + cdots + f[maxLength].
The time complexity is O(n), and the space complexity is O(n), where n=maxLength$.
Code
Python
Java
C++
Go
TypeScript
Detailed Complexity Analysis
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Recursion with Memoization | O(high) | O(high) | Useful for reasoning about the state transitions and converting a recursive idea into DP |
| Bottom-Up Dynamic Programming | O(high) | O(high) | Best general solution for interviews and competitive programming |
| Space-Optimized DP Counting | O(high) | O(high) | When implementing a clean iterative solution with minimal overhead |
Video Solution
Number of Good Binary Strings - LeetCode Premium • LeetCode Україна • 501 views views
Watch 1 more video solutions →Frequently Asked Questions
Is Number of Good Binary Strings easy or hard?
Number of Good Binary Strings Python/Java solution
How to solve Number of Good Binary Strings in O(n)?
What is the best approach for Number of Good Binary Strings?
Is Number of Good Binary Strings asked at Google/Amazon/Meta?
What data structure is used in Number of Good Binary Strings?
What is the time complexity of Number of Good Binary Strings?
Ready to solve this problem?
Practice Number of Good Binary Strings with our built-in code editor and test cases.
Practice on FleetCode