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 = ;
while (res * res <= n) ++res;
return res - ;
}
};

还有一种方法更简单,我们直接对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),只要有奇数个奇因子,那么灯就是灭的,只要有偶数个奇因子,那么灯就是亮的。

类似题目:

Bulb Switcher II

6.6 Toggle Lockers

参考资料:

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

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Bulb Switcher 灯泡开关的更多相关文章

  1. [LeetCode]319. Bulb Switcher灯泡开关

    智商压制的一道题 这个题有个数学定理: 一般数(非完全平方数)的因子有偶数个 完全平凡数的因子有奇数个 开开关的时候,第i个灯每到它的因子一轮的时候就会拨动一下,也就是每个灯拨动的次数是它的因子数 而 ...

  2. 319 Bulb Switcher 灯泡开关

    初始时有 n 个灯泡关闭. 第 1 轮,你打开所有的灯泡. 第 2 轮,每两个灯泡切换一次开关. 第 3 轮,每三个灯泡切换一次开关(如果关闭,则打开,如果打开则关闭).对于第 i 轮,你每 i 个灯 ...

  3. Leetcode319. Bulb Switcher灯泡开关

    初始时有 n 个灯泡关闭. 第 1 轮,你打开所有的灯泡. 第 2 轮,每两个灯泡你关闭一次. 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭).第 i 轮,每 i 个灯泡切换一次 ...

  4. [LeetCode] Bulb Switcher II 灯泡开关之二

    There is a room with n lights which are turned on initially and 4 buttons on the wall. After perform ...

  5. LeetCode Bulb Switcher 319

    变换灯泡颜色 There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off ...

  6. Leetcode Bulb Switcher

    There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every ...

  7. 【LeetCode】319. Bulb Switcher 解题报告(Python)

    [LeetCode]319. Bulb Switcher 解题报告(Python) 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/bulb ...

  8. LeetCode 319 ——Bulb Switcher——————【数学技巧】

    319. Bulb Switcher My Submissions QuestionEditorial Solution Total Accepted: 15915 Total Submissions ...

  9. Leetcode 319.灯泡开关

    灯泡开关 初始时有 n 个灯泡关闭.第 1 轮,你打开所有的灯泡.第 2 轮,每两个灯泡你关闭一次.第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭).第 i 轮,每 i 个灯泡切换 ...

随机推荐

  1. Web安全相关(二):跨站请求伪造(CSRF/XSRF)

    简介 CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对 ...

  2. 作为一个程序猿,是不是经常会用到.chm文档,但是我们可能会遇到这样那样的问题,比如.chm文档打不开

    .chm文档不能正常打开,一般有两种情形下会造成文档打不开, 1.系统语言栏的语言和文档的语言类别不一同,也就是说比如你的文档是中文版的,但是系统设置的语言是其他国家的.不过一般这种情况很少出现 ,谁 ...

  3. 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务

      上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...

  4. 利用Python进行数据分析(4) NumPy基础: ndarray简单介绍

    一.NumPy 是什么 NumPy 是 Python 科学计算的基础包,它专为进行严格的数字处理而产生.在之前的随笔里已有更加详细的介绍,这里不再赘述. 利用 Python 进行数据分析(一)简单介绍 ...

  5. Jquery中的bind(),live(),delegate(),on()绑定事件方式

    博客转载为作者:枫上善若水http://www.cnblogs.com/xilipu31/p/4105794.html 前言 因为项目中经常会有利用jquery操作dom元素的增删操作,所以会涉及到d ...

  6. javascript性能优化:创建javascript无阻塞脚本

    javaScript 在浏览器中的运行性能,在web2.0时代显得尤为重要,成千上万行javaScript代码无疑会成为性能杀手, 在较低版本的浏览器执行JavaScript代码的时候,由于浏览器只使 ...

  7. Sqlserver调用api

    虽然使用sqlserver去调用服务接口的情况比较少,但也可以去了解下对应的使用情况 一.首先要开启组件的配置 sp_configure ; GO RECONFIGURE; GO sp_configu ...

  8. ubuntu Chromium 安装 pepperflashplugin

    sudo apt-get update sudo apt-get install chromium-browser sudo apt-get install pepperflashplugin-non ...

  9. java类的初始化顺序

    在java中,当我们new一个对象时,对象中的成员,初始化块以及构造方法的加载是有一定的顺序的,看下面一副图: 一.单类(无基类)下的初始化顺序: public class Parent { stat ...

  10. java范型集合中的成员排序

    范型集合中的类是JsonObject,不是自定义类,如果是自定义类就直接取要比较的字段值. ArrayList<JSONObject> TList = new ArrayList<J ...