3129. 找出所有稳定的二进制数组 I
给你 3 个正整数 zero
,one
和 limit
。
一个 二进制数组 arr
如果满足以下条件,那么我们称它是 稳定的 :
arr
中出现次数 恰好 为 zero
。arr
中出现次数 恰好 为 one
。arr
中每个长度超过 limit
的 子数组 都 同时 包含 0 和 1 。请你返回 稳定 二进制数组的 总 数目。
由于答案可能很大,将它对 109 + 7
取余 后返回。
示例 1:
输入:zero = 1, one = 1, limit = 2
输出:2
解释:
两个稳定的二进制数组为 [1,0]
和 [0,1]
,两个数组都有一个 0 和一个 1 ,且没有子数组长度大于 2 。
示例 2:
输入:zero = 1, one = 2, limit = 1
输出:1
解释:
唯一稳定的二进制数组是 [1,0,1]
。
二进制数组 [1,1,0]
和 [0,1,1]
都有长度为 2 且元素全都相同的子数组,所以它们不稳定。
示例 3:
输入:zero = 3, one = 3, limit = 2
输出:14
解释:
所有稳定的二进制数组包括 [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]
和 [1,1,0,1,0,0]
。
提示:
1 <= zero, one, limit <= 200
原站题解
golang 解法, 执行用时: 7 ms, 内存消耗: 6.8 MB, 提交时间: 2024-05-01 10:52:33
func numberOfStableArrays(zero, one, limit int) (ans int) {const mod = 1_000_000_007f := make([][][2]int, zero+1)for i := range f {f[i] = make([][2]int, one+1)}for i := 1; i <= min(limit, zero); i++ {f[i][0][0] = 1}for j := 1; j <= min(limit, one); j++ {f[0][j][1] = 1}for i := 1; i <= zero; i++ {for j := 1; j <= one; j++ {f[i][j][0] = (f[i-1][j][0] + f[i-1][j][1]) % modif i > limit {// + mod 保证答案非负f[i][j][0] = (f[i][j][0] - f[i-limit-1][j][1] + mod) % mod}f[i][j][1] = (f[i][j-1][0] + f[i][j-1][1]) % modif j > limit {f[i][j][1] = (f[i][j][1] - f[i][j-limit-1][0] + mod) % mod}}}return (f[zero][one][0] + f[zero][one][1]) % mod}
cpp 解法, 执行用时: 11 ms, 内存消耗: 13.6 MB, 提交时间: 2024-05-01 10:52:20
class Solution {public:int numberOfStableArrays(int zero, int one, int limit) {const int MOD = 1'000'000'007;vector<vector<array<int, 2>>> f(zero + 1, vector<array<int, 2>>(one + 1));for (int i = 1; i <= min(limit, zero); i++) {f[i][0][0] = 1;}for (int j = 1; j <= min(limit, one); j++) {f[0][j][1] = 1;}for (int i = 1; i <= zero; i++) {for (int j = 1; j <= one; j++) {// + MOD 保证答案非负f[i][j][0] = ((long long) f[i - 1][j][0] + f[i - 1][j][1] + (i > limit ? MOD - f[i - limit - 1][j][1] : 0)) % MOD;f[i][j][1] = ((long long) f[i][j - 1][0] + f[i][j - 1][1] + (j > limit ? MOD - f[i][j - limit - 1][0] : 0)) % MOD;}}return (f[zero][one][0] + f[zero][one][1]) % MOD;}};
java 解法, 执行用时: 18 ms, 内存消耗: 43.8 MB, 提交时间: 2024-05-01 10:51:26
class Solution {public int numberOfStableArrays(int zero, int one, int limit) {final int MOD = 1_000_000_007;int[][][] f = new int[zero + 1][one + 1][2];for (int i = 1; i <= Math.min(limit, zero); i++) {f[i][0][0] = 1;}for (int j = 1; j <= Math.min(limit, one); j++) {f[0][j][1] = 1;}for (int i = 1; i <= zero; i++) {for (int j = 1; j <= one; j++) {// + MOD 保证答案非负f[i][j][0] = (int) (((long) f[i - 1][j][0] + f[i - 1][j][1] + (i > limit ? MOD - f[i - limit - 1][j][1] : 0)) % MOD);f[i][j][1] = (int) (((long) f[i][j - 1][0] + f[i][j - 1][1] + (j > limit ? MOD - f[i][j - limit - 1][0] : 0)) % MOD);}}return (f[zero][one][0] + f[zero][one][1]) % MOD;}}
python3 解法, 执行用时: 398 ms, 内存消耗: 28.9 MB, 提交时间: 2024-05-01 10:50:38
class Solution:def numberOfStableArrays(self, zero: int, one: int, limit: int) -> int:MOD = 1_000_000_007@cache # 缓存装饰器,避免重复计算 dfs 的结果(记忆化)# dfs(i,j,k) 表示用 i 个 0 和 j 个 1 构造稳定数组的方案数,# 其中第 i+j 个位置要填 k,其中 k 为 0 或 1。def dfs(i: int, j: int, k: int) -> int:if i == 0:return 1 if k == 1 and j <= limit else 0if j == 0:return 1 if k == 0 and i <= limit else 0if k == 0:return (dfs(i - 1, j, 0) + dfs(i - 1, j, 1) - (dfs(i - limit - 1, j, 1) if i > limit else 0)) % MODelse: # else 可以去掉,这里仅仅是为了代码对齐return (dfs(i, j - 1, 0) + dfs(i, j - 1, 1) - (dfs(i, j - limit - 1, 0) if j > limit else 0)) % MODans = (dfs(zero, one, 0) + dfs(zero, one, 1)) % MODdfs.cache_clear() # 防止爆内存return ans# 递推def numberOfStableArrays2(self, zero: int, one: int, limit: int) -> int:MOD = 1_000_000_007f = [[[0, 0] for _ in range(one + 1)] for _ in range(zero + 1)]for i in range(1, min(limit, zero) + 1):f[i][0][0] = 1for j in range(1, min(limit, one) + 1):f[0][j][1] = 1for i in range(1, zero + 1):for j in range(1, one + 1):f[i][j][0] = (f[i - 1][j][0] + f[i - 1][j][1] - (f[i - limit - 1][j][1] if i > limit else 0)) % MODf[i][j][1] = (f[i][j - 1][0] + f[i][j - 1][1] - (f[i][j - limit - 1][0] if j > limit else 0)) % MODreturn sum(f[-1][-1]) % MOD