题目:
给你 3 个正整数 zero ,one 和 limit 。
一个 二进制数组 arr 如果满足以下条件,那么我们称它是 稳定的 :
- 0 在
arr中出现次数 恰好 为zero。 - 1 在
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]。
思考
这个题实际上一上来就给了一个固定长度的数组,我们要做的是把确定数量的 0 和 1 放入数组中并其实符合条件。并且不难想到的是:
如果当前长度为 x ,可以组合的数量为 m,那么在加入一个 0 或 1,如果全部符合条件 , 可以组合的数量就是 2m,但是我们还有剔除所有不符合条件的情况,即有了连续 limit + 1 个 0 或 1。
既然是我们放入了第 x + 1 个数据后才导致的数据不符合条件,那么这一串连续的数据必然在数组的末尾,例如,如果我们最后放入一个 1 导致数据不合法了,那么目前的数组组成就是 :一串合法的数据 + 0 + limit+1个1 。所有我们要减去一串合法的数据 + 0 这一串数组可以组合的数量。
代码实现
class Solution {
public int numberOfStableArrays(int zero, int one, int limit) {
// 按照题目要求进行取模
final int MOD = 1000000007;
// 用 i 表示已经放入 0 的数量
// 用 j 表示已经放入 1 的数量
// 用 lastBit 表示当前数组的最后一位是 0 还是 1
int[][][] dp = new int[zero + 1][one + 1][2];
for(int i = 0 ; i <= zero; i ++){
for(int j = 0;j <= one; j ++){
for(int lastBit = 0 ;lastBit <= 1; lastBit ++){
// 初始化阶段
if(i == 0){
if(lastBit == 0 || j > limit){
// lastBit == 0 与 i == 0 两个条件互斥
// j > limit 且 i == 0 时这个数组一定是不合法的
dp[i][j][lastBit] = 0;
}else{
// 0 个 1 和 j 个 i,共组成了 1 个可能的情况(全是1)
dp[i][j][lastBit] = 1;
}
}else if(j == 0){ // j == 0 的初始化同理
if(lastBit == 1 || i > limit){
dp[i][j][lastBit] = 0;
}else {
dp[i][j][lastBit] = 1;
}
}else if(lastBit == 0){
// 先不考虑 数组不合法 的情况
dp[i][j][lastBit] =dp[i - 1][j][0] + dp[i - 1][j][1];
// 按照上面的分析进行扣减
if(i > limit){
dp[i][j][lastBit] -= dp[i - limit - 1][j][1];
}
}else {
dp[i][j][lastBit] = dp[i][j - 1][0] + dp[i][j - 1][1];
if(j > limit){
dp[i][j][lastBit] -=dp[i][j - limit - 1][0];
}
}
dp[i][j][lastBit] %= MOD;
if(dp[i][j][lastBit] < 0){
dp[i][j][lastBit] += MOD;
}
}
}
}
return (dp[zero][one][0] + dp[zero][one][1]) % MOD;
}
}Java
Comments NOTHING