难度:中等
初始时有 n
个灯泡处于关闭状态。第一轮,你将会打开所有灯泡。接下来的第二轮,你将会每两个灯泡关闭第二个。
第三轮,你每三个灯泡就切换第三个灯泡的开关(即,打开变关闭,关闭变打开)。第 i
轮,你每 i
个灯泡就切换第 i
个灯泡的开关。直到第 n
轮,你只需要切换最后一个灯泡的开关。
找出并返回 n
轮后有多少个亮着的灯泡。
输入:n = 3
输出:1
解释:
初始时, 灯泡状态 [关闭, 关闭, 关闭].
第一轮后, 灯泡状态 [开启, 开启, 开启].
第二轮后, 灯泡状态 [开启, 关闭, 开启].
第三轮后, 灯泡状态 [开启, 关闭, 关闭].
你应该返回 1,因为只有一个灯泡还亮着。
输入:n = 0
输出:0
输入:n = 1
输出:1
如果我们将所有的灯泡从左到右依次编号为1、2、...、n
,那么可以发现:在第i
轮的时候,我们会将所有为i
的倍数的灯泡进行切换。
因此,对于第k
个灯泡,它被切换的次数恰好就是k的约数个数。如果k
有偶数个约数,那么最终第k
个灯泡的状态就为暗,如果k
有奇数个约数,那么最终第k个灯泡的状态就为亮。
对于k而言,如果它有约数x
,那么一定有约数k/x
,因此只要x²≠k
时,约数都是成对出现的。这就是说明,只有当k
是完全平方数时,它才有奇数个约数,否则一定有偶数个约数。
因此我们只需要找出1、2、...、n
中的完全平方数的个数即可,答案即为 ⌊√n⌋
,其中 ⌊⋅⌋
表示向下取整。
由于√n
涉及到浮点数运算,为了保证不出现精度问题,我们可以计算√(n + 0.5)
,这样可以保证计算出来的结果向下取整在32位整数范围内一定正确
/**
* 数学
* @desc 时间复杂度 O(1) 空间复杂度 O(1)
* @param n
* @returns
*/
export function bulbSwitch(n: number): number {
return Math.sqrt(n + 0.5) >> 0
}