面试算法高频压轴题——灯泡开关问题

题意

一个圆环上有100个灯泡,灯泡有亮和暗两种状态。灯泡的状态随机,按一个灯泡的开关,相邻两个灯泡的状态会发生一次改变。比如暗~亮~暗,按中间的灯泡,变化为亮~暗~亮。请设计一道算法,使得所有灯泡最后全部变为亮色。

思路分析

第一步:把所有灯泡变为全亮或者只剩一个是暗的

给所有灯泡编号为1~100,对于1~98号的灯泡,遇到暗的,就按下它的相邻灯泡的开关,保证它是亮的(也就是在牺牲紧接着的后一个灯泡的亮度的可能下,保证当前灯泡是亮的),这样一直遍历下去,就能保证1~98号灯泡是亮的。我们已经保证1~98号灯泡是亮的,最后两个灯泡可能是:

  • 亮-亮:皆大欢喜
  • 亮-暗、暗-亮:只剩一个为暗的情况
  • 暗-暗:按下第100号灯泡的开关,使99号和100号变亮,1号变为暗,也变成只剩一个为暗

第二步:将所有灯泡全部变暗 

我们现在对经由第一步处理后剩下一个暗色灯泡的情况做处理。由于灯泡按环形摆放,我们指定唯一的暗灯泡为1号,其他剩余的99个亮灯泡,规定每3个位一组 ,按下每组亮灯泡的中间一个,使得每组3个灯泡全部变暗,从而使全部灯泡变暗。

第三步:将所有灯泡全部变亮

将所有灯泡按1~n的次序按一遍,就全变亮了

下面以n为7为例,模拟了一下这个过程(赶时间,画的比较粗糙):

面试算法高频压轴题——灯泡开关问题_第1张图片


扩展

对于N个灯泡的任意初始状态(N>3),能否经过若干次操作使得灯泡全部变亮——对N分类讨论

  • 【N = 3*k + 1】,一定可以。方法与上述步骤相同。
  • 【N = 3*k + 2】,一定可以。将上述步骤一的目标状态的只剩一个为暗改为剩两个相邻为暗,其余3*k 个灯泡按照上述步骤二分组按即可,以达到全部变暗的目的,再按步骤三操作。
  • 【N = 3*k】,不一定。若经过步骤一使得全部灯泡变亮则有解,否则无解(需证明)

总结

对于这道题,有以下两个等价关系:

全暗 <=> 全亮。全暗和全亮两种状态可以相互转化,方法就是每个灯泡依次按一次,这样每个灯泡都被改变了3次状态,奇数次改变变为相反的状态。  

剩一个为暗 <=> 剩两个为暗。剩余一个为暗时,按下该灯泡左右任意一个,就变成了剩余两个相邻为暗的情况;剩余两个相邻为暗时,按下第二个暗,就变成了剩下一个为暗的情况。

借鉴_小co

你可能感兴趣的:(数据结构与算法,面试宝囊,面试,算法)