第474题 监狱牢房变化问题
1.题目分析
该问题状态属于模拟类问题,需要模拟牢房的状态转变。每间牢房的状态(占用或空置)受到其左右相邻房间状态的影响,第一个和最后一个房间不变。我们需要:
- 根据初始状态
cells模拟状态的变化。 - 确定了经过
n天后的最终状态。
问题的重点在于:
- 每天需要更新整个
cells数据库。 - 当
n很大的时候,逐天模拟就会导致性能瓶颈。 - 因此,需要利用状态变化的周期性进行优化。
2.解题思路
-
逐日模拟状态变化:
- 根据规则生成下一天的状态。
- 第一个和最后一个牢房不变,其余牢房状态通过比较左右邻居决定。
-
优化国家计算:
- 如果
n很大,可以观察是否状态重复。 - 一旦检测到状态开始重复,就说明进入了周期,可以通过
n % cycle_length直接确定剩余天数。
- 如果
-
终止条件:
- 若未出现周期,则模拟完整的
n天。 - 如果进入对应周期,直接计算剩余天数的状态,避免计算。
- 若未出现周期,则模拟完整的
3.解题代码
def solution(cells: list, n: int) -> list:
seen = {} # 用于记录状态及其出现的天数
is_fast_forwarded = False
for day in range(n):
if not is_fast_forwarded:
state_tuple = tuple(cells)
if state_tuple in seen: # 如果状态已出现,进入循环模式
cycle_length = day - seen[state_tuple]
n %= cycle_length # 剩下的天数通过循环优化
is_fast_forwarded = True
else:
seen[state_tuple] = day
if n > 0: # 继续模拟剩余天数
new_cells = [0] * len(cells)
for i in range(1, len(cells) - 1):
new_cells[i] = 1 if cells[i - 1] == cells[i + 1] else 0
cells = new_cells
n -= 1
return cells
if __name__ == '__main__':
print(solution(cells=[0, 1, 0, 1, 1, 0, 1], n=7) == [0, 1, 1, 1, 0, 1, 0])
print(solution(cells=[1, 0, 0, 1, 0, 1, 0], n=12500) == [0, 1, 0, 0, 1, 0, 0])
print(solution(cells=[1, 1, 0, 0, 0, 0, 1, 1, 1], n=6) == [0, 1, 0, 0, 1, 0, 0, 1, 0])
print(solution(cells=[0, 0, 1, 1, 0, 0, 1, 1], n=10) == [0, 0, 1, 1, 1, 1, 0, 0])
4.模块解释
1.状态更新模块:
new_cells = [0] * len(cells)
for i in range(1, len(cells) - 1):
new_cells[i] = 1 if cells[i - 1] == cells[i + 1] else 0
cells = new_cells
-
更新
cells信息:- 使用新的仓库
new_cells每天的变化结果。 - 中间的牢房通过左右邻居的状态更新。
- 第一个和最后一个牢房始终为0。
- 使用新的仓库
2.周期检测模块:
state_tuple = tuple(cells)
if state_tuple in seen:
cycle_length = day - seen[state_tuple]
n %= cycle_length
is_fast_forwarded = True
else:
seen[state_tuple] = day
-
使用哈希表
seen检测状态是否重复:- 若当前状态已经出现过,则计算周期。
- 用
n % cycle_length减少模拟天数。
3.快速跳过周期模块:
if not is_fast_forwarded:
n %= cycle_length
is_fast_forwarded = True
- 通过跳过枢轴计算,效率显着提升。
4.模拟剩余天数模块:
if n > 0:
cells = new_cells
n -= 1
- 在优化后,继续模拟剩余的
n天,方案完成
总结:
-
优势:
- 利用周期性显著减少计算量,特别适合
n非常大的情况。 - 哈希表的使用避免了重复状态的冗余模拟。
- 利用周期性显著减少计算量,特别适合
-
性能:
- 最优情况下复杂度接近 O(k + n mod cycle_length),其中 kkk 是牢房数。
- 最坏情况下复杂度为 O(k⋅n),仅在状态无周期时发生。
-
适用性:
- 该代码解决了任意大小的
n和cells状态输入,特别适合处理周期性问题。 - 若周期较短,优化效果更显著。
- 该代码解决了任意大小的
-
输出准确性:
- 所有测试样例均能输出正确结果。周期检测有效避免了性能瓶颈,使得计算更加高效。