问题描述
给你100盏灯围成一个圆环,灯有两种状态,要么是亮的要么是灭的,灯的初始状态是随机的。每个灯有一个开关,灯的开关具有这样的作用,按一下某个灯的开关,则该灯以及它相邻的两个灯的状态都会发生一次变化,即亮的变成暗的,暗的变成亮的。例如亮–亮--亮,按下中间的开关,则三盏灯全灭,亮–暗--暗,按下中间的开关,变成暗–亮--亮… 问你有没有办法使得100盏灯全亮,如果有,请说明你的算法思路。
算法解决
1 如果一共有99盏灯是全灭的,那么很容易就想到如何全部点亮,那么此时如果有100盏灯是全灭的,怎么全部点亮
可以发现不管是100盏灯还是101盏灯,按照从0开始依次按就可以全部点亮。
2 如果100盏灯中有一盏灯是亮的的,那么就是剩下99盏灯是全灭的,应该很好解决
所以现在的问题就是如果获得全灭的灯,可以先遍历从0到97盏灯,遇到亮的就按灭,那么最后剩下第98和第99盏灯,此时就分几种情况了 2.1 如果第98和第99盏灯全灭的话,那就等于转换为了100栈全灭的灯了 2.2 如果第98和第99盏灯中有一盏灯是亮的话,那么此时就转换为了只有一盏灯是亮的情况了。
3 怎么想到是灯全灭的这种情况呢?
因为输入的状态的灯是随机的,所以处理的时候得需要统一处理一下
代码
function triggle(list, i) {
if (i < 0 || i > list.length - 1) {
return;
}
list[i] = list[i] === 1 ? 0 : 1;
if (i === 0) {
if (list.length > 2) {
list[list.length - 1] = list[list.length - 1] === 1 ? 0 : 1;
}
list[1] = list[1] === 1 ? 0 : 1;
} else if (i === list.length - 1) {
if (list.length > 2) {
list[list.length - 2] = list[list.length - 2] === 1 ? 0 : 1;
}
list[0] = list[0] === 1 ? 0 : 1;
} else {
list[i + 1] = list[i + 1] === 1 ? 0 : 1;
list[i - 1] = list[i - 1] === 1 ? 0 : 1;
}
}
function triggleAllLeds(lists) {
for (let i = 0; i < lists.length - 2; i++) {
if (lists[i] === 1) {
triggle(lists, i + 1);
}
}
if (lists[lists.length - 1] === 0 && lists[lists.length - 2] === 0) {
for (let i = 0; i < lists.length; i++) {
triggle(lists, i);
}
return lists;
} else if (lists[lists.length - 1] === 1 && lists[lists.length - 2] === 0) {
for (let i = 1; i < lists.length - 2; i += 3) {
triggle(lists, i);
}
return lists;
} else if (lists[lists.length - 1] === 0 && lists[lists.length - 2] === 1) {
for (let i = 0; i < lists.length - 3; i += 3) {
triggle(lists, i);
}
return lists;
} else {
triggle(lists, 98);
triggle(lists, 99);
for (let i = 2; i < lists.length - 4; i += 3) {
triggle(lists, i);
}
return lists;
}
}
export default triggleAllLeds;