iOS LeetCode ? 灯泡问题
初始时有 n 个灯泡处于关闭状态。对某个灯泡切换开关意味着:如果灯泡状态为关闭,那该灯泡就会被开启;而灯泡状态为开启,那该灯泡就会被关闭。第 1 轮,每个灯泡切换一次开关。即,打开所有的灯泡。第 2 轮,每两个灯泡切换一次开关。 即,每两个灯泡关闭一个。第 3 轮,每三个灯泡切换一次开关。第 i 轮,每 i 个灯泡切换一次开关。 而第 n 轮,你只切换最后一个灯泡的开关。找出 n 轮后有多少个亮着
初始时有 n
个灯泡处于关闭状态。
对某个灯泡切换开关意味着:如果灯泡状态为关闭,那该灯泡就会被开启;而灯泡状态为开启,那该灯泡就会被关闭。
第 1 轮,每个灯泡切换一次开关。即,打开所有的灯泡。
第 2 轮,每两个灯泡切换一次开关。 即,每两个灯泡关闭一个。
第 3 轮,每三个灯泡切换一次开关。
第 i
轮,每 i
个灯泡切换一次开关。 而第 n
轮,你只切换最后一个灯泡的开关。
找出 n
轮后有多少个亮着的灯泡。
示例 1:
输入:n = 3
输出:1
解释:
初始时, 灯泡状态 [关闭, 关闭, 关闭].
第一轮后, 灯泡状态 [开启, 开启, 开启].
第二轮后, 灯泡状态 [开启, 关闭, 开启].
第三轮后, 灯泡状态 [开启, 关闭, 关闭].
你应该返回 1,因为只有一个灯泡还亮着。
示例 2:
输入:n = 0
输出:0
示例 3:
输入:n = 1
输出:1
提示:
- 0 <= n <= 109
解题思路
前言:
这是一道数学题,如果我们不理解一道数学题的规律前,我们就先开始枚举,然后发现其中的规律,这是解数学题的基操,不要偷懒,一定要把它枚举出来。这里我们慢慢的推进其分析过程!
枚举部分:
在拿到这道题前,如果没做过,我们肯定不能一眼洞悉其规律,因此我们要先发现这些数字间有什么关系。这里我列举了从 1 - 9
的情况,我本来以为是与 2
的次方有关系,结果发现并不是,于是列举 9
时发现了其规律。我们用 0表示off
, 1表示on
;
n
1: 1
2: 1 0
3: 1 0 0
4: 1 0 0 1
5: 1 0 0 1 0
6: 1 0 0 1 0 0
7: 1 0 0 1 0 0 0
8: 1 0 0 1 0 0 0 0
9: 1 0 0 1 0 0 0 0 1
解答部分:
至此,我们应该已经发现了,对于 n
的灯泡数量,在进行 n
轮的操作后,其实只跟 n
的平方根有关。发现这一点,对于解题已经没有难度了,很简单的一行代码就可以通过测试 return sqrt(n);
;
求证部分:
很多人跟我一样,总想明白其中的道理,不然觉得就算通过了也缺失点什么。这里我会用最简单的方法来让大家理解为什么是完全平方根!
首先长话短说:
- 对于一个完全平方数,它有
奇数个因子
- 而对于一个非完全平方数,它只有
偶数个因子
我们先看看一些非完全平方数(用大一点的数字好分析):
8 的因子: 1 2 4 8;
12 的因子:1 2 3 4 6 12;
我们发现这些总是偶数的个数,为什么呢,因为假设我有一个因子 x,那么 `n / x` 必然也是
n 的一个因子,它们总是成双成对的,比如 2 是12 的因子,那么 `12 / 2 = 6` 必然也是 12 的
因子,所以无论如何在 n 轮操作后它总是关闭的。
对于完全平方数:
4 的因子: 1 2 4;
16 的因子: 1 2 4 8 16;
我们发现它总是奇数个数,还是跟上面一样的道理,但是有一个特别的地方。那就是这个数
的平方根。假设 n 的平方跟为 x, 那么 x 必然是 n 的因子,然而 'n / x = x` 却不能成为
n 的另一个因子,它与 x 相同,因此我们只能计算一次。打个比方,对于 16 来说,它的
因子有:1 2 4 4 8 16,然而 4 这个数字重复了,因此我们只能计算一次,这也是它
为什么完全平方数是奇数因子的原因
代码
// 319. 灯泡开关
func bulbSwitch(_ n: Int) -> Int {
return Int(floor(sqrt(Double(n))))
}
更多推荐
所有评论(0)