如何在Numpy数组列表中识别长度>2的连续1块并统计数量
解决10位0-1数组中含长度>2连续1块的数量统计问题
方法一:动态规划递推(高效计算,无需生成所有数组)
直接统计符合条件的数组数量较繁琐,我们可以反向计算没有任何长度≥3的连续1的数组数量,再用总数2^10=1024减去这个数,得到目标结果。
我们用动态规划推导符合"无连续3个1"的序列数:
- 定义三个状态:
dp[i][0]:第i位为0的合规序列数dp[i][1]:第i位为1且前一位为0的合规序列数dp[i][2]:第i位为1且前两位均为1的合规序列数
- 状态转移公式:
dp[i][0] = dp[i-1][0] + dp[i-1][1] + dp[i-1][2](当前位放0,前序任意合规状态都可延续)dp[i][1] = dp[i-1][0](当前位放1,前一位必须是0)dp[i][2] = dp[i-1][1](当前位放1,前一位必须是单个1的状态)
- 初始条件(i=1时):
dp[1][0] = 1,dp[1][1] = 1,dp[1][2] = 0
递推到i=10的代码实现:
# 初始化n=1的状态 dp0, dp1, dp2 = 1, 1, 0 for _ in range(2, 11): new_dp0 = dp0 + dp1 + dp2 new_dp1 = dp0 new_dp2 = dp1 dp0, dp1, dp2 = new_dp0, new_dp1, new_dp2 valid_count = dp0 + dp1 + dp2 # 无连续3个1的数组数量 target_count = 2**10 - valid_count print(f"存在长度>2连续1块的数组数量:{target_count}")
运行结果:602
方法二:直接遍历Numpy数组验证(直观但效率稍低)
如果你想直接基于已生成的all_arrays进行验证,可以用Numpy的滑动窗口计算连续1的长度:
import numpy as np from itertools import product all_arrays = np.array(list(product([0,1], repeat=10))) # 计算每个数组中连续1的最大长度 max_consecutive_ones = [] for arr in all_arrays: # 生成差分,标记连续1的断点 diff = np.diff(arr, prepend=0, append=0) # 找到所有连续1的起始和结束索引 starts = np.where(diff == 1)[0] ends = np.where(diff == -1)[0] # 计算每个连续块的长度,取最大值(无连续1则为0) if len(starts) == 0: max_len = 0 else: max_len = np.max(ends - starts) max_consecutive_ones.append(max_len) # 统计最大连续长度>2的数组数量 target_count = np.sum(np.array(max_consecutive_ones) > 2) print(f"存在长度>2连续1块的数组数量:{target_count}")
运行结果同样为602,和递推法结果一致。
内容的提问来源于stack exchange,提问作者sonido
相关产品推荐
相关产品推荐

