319.灯泡开关
题目描述
思路
数学
根据题意,总共有n个灯泡,对于除了第一轮外的每轮都对轮数的倍数的灯泡进行切换。如总共10个灯泡,在第2轮,需要切换5个灯泡,第3轮,切换3个灯泡,第4轮,切换2个灯泡,第5轮,切换2个灯泡…以此类推。
因此,对于第k个灯泡,被切换的次数恰好是k的约数的个数。如果k有偶数个约数,则最终第k个灯泡状态为关闭;如果k有奇数个约数,则最终第k个灯泡状态为打开。
那么什么时候出现偶数个约数,什么时候出现奇数个约数呢?对于数字k,假定它有约数a,则一定有约数
b
=
k
/
a
b=k/a
b=k/a,因此只要当
a
2
≠
k
a^2≠k
a2=k时,则所有的约数都是成对出现的,因此是偶数个约数。而当k是完全平方数时,才会有奇数个约数。
因此只需要找到1、2、…、n中的完全平方数个数即可。
而求范围内完全平方数的个数可以转化为求范围内完全平方数的平方根的个数。即可转化为对n求平方根,并向下取整,即可找到范围内的完全平方数的个数。
另外,为保证不出现精度问题,可以对n+0.5计算平方根,可以保证计算出的结果向下取整在32位整数范围内一定正确。
Java实现
class Solution {
public int bulbSwitch(int n) {
return (int) Math.sqrt(n+0.5);
}
}
Python实现
class Solution:
def bulbSwitch(self, n: int) -> int:
return int(sqrt(n+0.5))