题目
传送门:灯泡开关
初始时有 n 个灯泡关闭。
第 1 轮,你打开所有的灯泡。 第 2 轮,每两个灯泡你关闭一次。 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭)。
第 i 轮,每 i 个灯泡切换一次开关。 对于第 n 轮,你只切换最后一个灯泡的开关。
找出 n 轮后有多少个亮着的灯泡。
思路
开始思维很简单:如果我要知道n个灯泡的开关情况,只需要知道n-1个灯泡的情况+第n个灯泡的情况;而第n个灯泡的情况很显然跟它的因子个数相关。比如12有6个因子,经过偶数次开关,灯泡为暗。由此得到以下代码:
1 | class Solution { |
那么很显然,这个代码的时间复杂度为O(n²)。
在n=99999时就已经超时了。
接下来,我对计算因子个数的方法进行了优化:
1 | class Solution { |
这比循环n/2次快了许多,但仍然在最后9999999时超时了。
看来按照一开始的思路注定是走不通了。
先上代码
1 | class Solution { |
很神奇,但这是为什么呢?
在之前的思路中,我们都是通过计算一个数的因子个数来判断灯泡的亮暗情况。事实上,我们无需计算个数,只需知晓个数奇偶就行。通过观察发现,大部分因子都是成双成对的,只有一种可能,那就是平方数,只有平方数拥有奇数个因子,它们的灯泡才会亮。问题迎刃而解。
总结
这是一道很有意思的题,设置的非常巧妙。妙啊