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 nth round, you only toggle the last bulb. Find how many bulbs are on after n rounds.
Example:
Given n = 3.
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.
這道題給了我們n個燈泡,第一次打開所有的燈泡,第二次每兩個更改燈泡的狀態,第三次每三個更改燈泡的狀態,以此類推,第n次每n個更改燈泡的狀態。讓我們求n次后,所有亮的燈泡的個數。此題是CareerCup 6.6 Toggle Lockers 切換鎖的狀態。
那么我們來看這道題吧,還是先枚舉個小例子來分析下,比如只有5個燈泡的情況,'X'表示滅,‘√’表示亮,如下所示:
初始狀態: X X X X X
第一次: √ √ √ √ √
第二次: √ X √ X √
第三次: √ X X X √
第四次: √ X X √ √
第五次: √ X X √ X
那么最后我們發現五次遍歷后,只有1號和4號燈泡是亮的,而且很巧的是它們都是平方數,是巧合嗎,還是其中有什么玄機。我們仔細想想,對於第n個燈泡,只有當次數是n的因子的之后,才能改變燈泡的狀態,即n能被當前次數整除,比如當n為36時,它的因數有(1,36), (2,18), (3,12), (4,9), (6,6), 可以看到前四個括號里成對出現的因數各不相同,括號中前面的數改變了燈泡狀態,后面的數又變回去了,等於燈泡的狀態沒有發生變化,只有最后那個(6,6),在次數6的時候改變了一次狀態,沒有對應其它的狀態能將其變回去了,所以燈泡就一直是點亮狀態的。所以所有平方數都有這么一個相等的因數對,即所有平方數的燈泡都將會是點亮的狀態。
那么問題就簡化為了求1到n之間完全平方數的個數,我們可以用force brute來比較從1開始的完全平方數和n的大小,參見代碼如下:
解法一:
class Solution { public: int bulbSwitch(int n) { int res = 1; while (res * res <= n) ++res; return res - 1; } };
還有一種方法更簡單,我們直接對n開方,在C++里的sqrt函數返回的是一個整型數,這個整型數的平方最接近於n,即為n包含的所有完全平方數的個數,參見代碼如下:
解法二:
class Solution { public: int bulbSwitch(int n) { return sqrt(n); } };
討論:這道題有個follow up就是,如果我們toggle的順序不是1,2,3,4...,而是1,3,5,7...,或者是2,4,6,8... 的話,還怎么做?博主沒有想出像解法二那樣簡便的方法,只是大概想了想,如果各位大神有更好的方法,請一定要在下方留言啊。博主想的是,比如對於1,3,5,7...,那么就是先把所有的燈點亮,然后關掉3,6,9,12,15...等的燈,然后toggle的是5,10,15...等等,然后再toggle的是7,14,21...,我們發現,純2的倍數的燈永遠不會被改變,比如2,4,8,16... 這些燈狀態不會變,有些燈只會變一次,比如3,6,9等,而有些燈會變兩次,比如15(3x5),21(3x7),35(5x7)等,有些燈會變三次,比如105(3x5x7),那么我們可以觀察出規律了,toggle的次數跟奇數因子的數字有關(注意這里的奇數因子不包括1),只要有奇數個奇因子,那么燈就是滅的,只要有偶數個奇因子,那么燈就是亮的。
類似題目:
參考資料:
https://leetcode.com/problems/bulb-switcher/discuss/77104/Math-solution..
https://leetcode.com/problems/bulb-switcher/discuss/77112/Share-my-o(1)-solution-with-explanation