[LeetCode] Bulb Switcher
Posted Lin.B
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[LeetCode] Bulb Switcher相关的知识,希望对你有一定的参考价值。
There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it‘s off or turning off if it‘s on). For the i-th round, you toggle every i bulb. For the n-th round, you only toggle the last bulb. Find how many bulbs are on after n rounds.
Example:
Input: 3 Output: 1 Explanation: At first, the three bulbs are [off, off, off]. After first round, the three bulbs are [on, on, on]. After second round, the three bulbs are [on, off, on]. After third round, the three bulbs are [on, off, off]. So you should return 1, because there is only one bulb is on.
还是先枚举个小例子来分析下,比如只有5个灯泡的情况,‘X‘表示亮,‘√’表示灭,如下所示:
初始状态: X X X X X
第一次: √ √ √ √ √
第二次: √ X √ X √
第三次: √ X X X √
第四次: √ X X √ √
第五次: √ X X √ X
方法1:根据题意分析,很容易想到用两个循环来做,外循环用来循环次数,内循环用来改变灯泡的状态。这里用0表示关,1表示开。代码如下:
1 public int bulbSwitch(int n) { 2 int[] bulbs = new int[n]; 3 for ( int i = 0 ; i < n; i ++ ){ 4 for ( int j = i ; j < n ; j=j+i+1 ) 5 bulbs[j] = bulbs[j]==1?0:1; 6 } 7 int sum = 0; 8 for ( int i : bulbs ) sum+=i; 9 return sum; 10 }
思路和代码是正确的,但是时间复杂度太高,提交之后显示超时了,因此换了其他的解法。
方法2:参考@Grandyang的解题思路,整理如下:研究一下灯泡状态变化的规律,发现对于第n个灯泡,当次数是n的因子的时候,状态会改变,也就是n可以被i整除的时候改变状态。例如当n=36时,因子对有(1,36)(2,18)(3,12)(4,9)(6,6)。对于(1,36),第1次循环改变之后第36次循环又改变回来了,所以这个因子对实际对状态并没有发生改变,还是关状态。只有(6,6)这个因子本质上改变了灯泡的状态。因此我们只要寻找<=n的完全平方数就可以了。这里可以用暴力方法来寻找,代码如下:
1 public int bulbSwitch(int n) { 2 int res = 1; 3 while ( res * res <= n ) res++; 4 return res-1; 5 }
提交成功,时间为1ms,已经时很数学的方法了。
方法3:还有一种更简单的方法,直接对n求开方,得到的数就是n以内的完全平方数。刚开始还挺难理解的,被同学一句话点醒,因为比sqrt(n)小的整数i,其i^2一定小于n,所以直接返回sqrt(n)就可以了。代码就不放上去了,估计0ms。
总结一下,数学真美。
以上是关于[LeetCode] Bulb Switcher的主要内容,如果未能解决你的问题,请参考以下文章