You are given 3 positive integers num_zeros, num_ones, and limit.
A binary arrayarr is called stable if:
The number of occurrences of 0 in arr is exactly num_zeros.
The number of occurrences of 1 in arr is exactlynum_ones.
Each subarray of arr with a size greater than limit must contain at least one occurrence of both 0 and 1.
Return an integer denoting the total number of stable binary arrays.
Since the answer may be very large, return it modulo109 + 7.
Example 1:
Input:zero = 1, one = 1, limit = 2
Output:2
Explanation:
The two possible stable binary arrays are [1,0] and [0,1], as both arrays have a single 0 and a single 1, and no subarray has a length greater than 2.
Example 2:
Input:zero = 1, one = 2, limit = 1
Output:1
Explanation:
The only possible stable binary array is [1,0,1].
Note that the binary arrays [1,1,0] and [0,1,1] have subarrays of length 2 with identical elements, hence, they are not stable.
Example 3:
Input:zero = 3, one = 3, limit = 2
Output:14
Explanation:
All the possible stable binary arrays are [0,0,1,0,1,1], [0,0,1,1,0,1], [0,1,0,0,1,1], [0,1,0,1,0,1], [0,1,0,1,1,0], [0,1,1,0,0,1], [0,1,1,0,1,0], [1,0,0,1,0,1], [1,0,0,1,1,0], [1,0,1,0,0,1], [1,0,1,0,1,0], [1,0,1,1,0,0], [1,1,0,0,1,0], and [1,1,0,1,0,0].
Constraints:
1 <= zero, one, limit <= 200
Solutions
Solution 1: Memoized Search
Thinking
A stable array never has more than \(limit\) equal bits in a row. Backtracking over \(zero\) zeros and \(one\) ones explodes.
Validity after a prefix depends only on remaining zeros and ones and on which bit is written next. Overflow is the case of writing \(limit+1\) equal bits after the opposite bit.
Let \(dfs(i,j,k)\) be the number of ways with \(i\) zeros and \(j\) ones left and next bit \(k\). Add the same-color and other-color transitions and subtract the overflow term. Memoization yields \(O(zero\cdot one)\) states.
We define a function \(\textit{dfs}(i, j, k)\) to represent the number of stable binary arrays that satisfy the problem conditions when there are \(i\) zeros and \(j\) ones remaining to place, and the next digit to fill is \(k\). Then the answer is \(\textit{dfs}(\textit{zero}, \textit{one}, 0) + \textit{dfs}(\textit{zero}, \textit{one}, 1)\).
The computation process of \(\textit{dfs}(i, j, k)\) is as follows:
If \(i \lt 0\) or \(j \lt 0\), return \(0\).
If \(i = 0\), then return \(1\) when \(k = 1\) and \(j \leq \textit{limit}\); otherwise return \(0\).
If \(j = 0\), then return \(1\) when \(k = 0\) and \(i \leq \textit{limit}\); otherwise return \(0\).
If \(k = 0\), we consider the case where the previous digit is \(0\), i.e., \(\textit{dfs}(i - 1, j, 0)\), and the case where the previous digit is \(1\), i.e., \(\textit{dfs}(i - 1, j, 1)\). If the previous digit is \(0\), there may be more than \(\textit{limit}\) zeros in a subarray, which means the case where the \((\textit{limit} + 1)\)-th digit from the end is \(1\) is invalid, so we subtract this case: \(\textit{dfs}(i - \textit{limit} - 1, j, 1)\).
If \(k = 1\), we consider the case where the previous digit is \(0\), i.e., \(\textit{dfs}(i, j - 1, 0)\), and the case where the previous digit is \(1\), i.e., \(\textit{dfs}(i, j - 1, 1)\). If the previous digit is \(1\), there may be more than \(\textit{limit}\) ones in a subarray, which means the case where the \((\textit{limit} + 1)\)-th digit from the end is \(0\) is invalid, so we subtract this case: \(\textit{dfs}(i, j - \textit{limit} - 1, 0)\).
To avoid repeated computation, we use memoized search.
The time complexity is \(O(\textit{zero} \times \textit{one})\), and the space complexity is \(O(\textit{zero} \times \textit{one})\).
The recurrence has no aftereffect; recursion still pays cache and call overhead near the upper limits.
The same transition fills a table \(f[i][j][k]\): \(i\) zeros and \(j\) ones used, last bit \(k\).
Base cases are monochrome strings no longer than \(limit\). After iterating with a modulus, read \(f[zero][one][0]+f[zero][one][1]\).
We can also convert the memoized search in Solution 1 into dynamic programming.
We define \(f[i][j][k]\) as the number of stable binary arrays that use \(i\) zeros and \(j\) ones, with the last digit being \(k\). Then the answer is \(f[zero][one][0] + f[zero][one][1]\).
Initially, we have \(f[i][0][0] = 1\), where \(1 \leq i \leq \min(\textit{limit}, \textit{zero})\); and \(f[0][j][1] = 1\), where \(1 \leq j \leq \min(\textit{limit}, \textit{one})\).