传染字符串思路
2025-08-06 16:03:45
发布于:浙江
问题分析:
我们需要从给定的最终感染状态字符串 T,反推出可能的初始感染状态 S 中最少的感染个体('1')数量。传染规则是:每次操作中,感染个体('1')会将其左右相邻的健康个体('0')感染为 '1'。
核心观察:
- 初始感染个体经过 x 次传染后,会形成一个连续的 '1' 区域。例如,1 个初始 '1' 经过 x 次传染后,可形成长度为 2x+1 的连续 '1'(向左右各扩展 x 次)。
- 若初始 '1' 位于序列两端(左侧或右侧),经过 x 次传染后,可形成长度为 x+1 的连续 '1'(只能向一个方向扩展)。
- 最终状态中的连续 '1' 序列,是由初始的若干个 '1' 经过传染后可能重叠形成的。我们需要将这些连续 '1' 序列分解为最少的初始 '1'。
算法核心:
通过二分查找确定最大可能的传染次数 x,使得所有连续 '1' 序列都能被 x 次传染覆盖。对于每个 x,计算所需的最少初始 '1' 数量,最大 x 对应的数量即为答案(因为 x 越大,单个初始 '1' 能覆盖的范围越广,所需总数越少)。
步骤分解:
- 二分查找 x 的可能值:
o x 的范围从 0 到字符串长度(最大可能传染次数不会超过字符串长度)。
o 对于每个中间值 mid,检查是否所有连续 '1' 序列都能在 mid 次传染下形成(可行性检查)。 - 可行性检查(针对给定 x):
o 遍历字符串,拆分出所有连续的 '1' 序列。
o 对每个连续 '1' 序列:
o 若序列位于中间(左右均有 '0'):需满足序列长度 ≤ k*(2x+1)(k 为初始 '1' 数量),且 x 不能过大(否则单个初始 '1' 无法覆盖所需范围,即 x ≤ (序列长度 - 1)/2)。
o 若序列位于两端(左端或右端):需满足序列长度 ≤ k*(x+1),且 x 不能过大(即 x ≤ 序列长度 - 1)。
o 若所有序列都满足上述条件,则 x 可行。 - 计算初始 '1' 数量:
o 对于可行的 x,对每个连续 '1' 序列计算所需初始 '1' 数量:
o 中间序列:ceil (序列长度 / (2x+1))
o 两端序列:ceil (序列长度 / (x+1))
o 总和即为该 x 对应的最少初始 '1' 数量。
o 结果:二分查找得到最大可行 x 后,对应的初始 '1' 数量总和即为答案。
这里空空如也







有帮助,赞一个