题目描述
最开始有n个灯泡,编号从1到n,都是灭的。
第一次打开所有灯泡;
第二次按下编号是偶数的灯泡开关(亮的变灭,灭的变亮);
第三次按下编号是3的倍数的灯泡开关;
…
第n次按下最后一个灯泡的开关。
请问最终有多少个灯泡是亮的。
样例
输入:3
输出:1
解释:
最开始三个灯泡的状态是 [灭,灭,灭];
第一次按开关以后变成:[亮,亮,亮];
第二次按开关以后变成:[亮,灭,亮];
第三次按开关以后变成:[亮,灭,灭];
算法
(数论) O(1)
每个灯泡开关被按的次数等于它的编号的约数个数。
最终灯泡是亮的,说明编号有奇数个约数。
下面我们证明:一个数有奇数个约数,等价于它是平方数。
证明:
首先,对于每个平方数,除了平方根之外,其余所有约数都是成对出现,所以平方数有奇数个约数。
然后,由算数基本定理,一个整数 n 可以唯一表示成:n=pk11×pk22×…×pkmm。其中 p1,…pm 均是质数,k1,…km 均是正整数。
则 n 的约数个数就是 ∏mi=1(ki+1)。
如果 n 有奇数个约数,说明 (k1+1),…(km+1) 都是奇数,从而 k1,…km 均是偶数。所以 n=(pk1/21×pk2/22×…×pkm/2m)2,所以 n 是平方数。
假设共有 n 个灯泡,则从 1 到 n 中共有 ⌊√n⌋ 个平方数。
时间复杂度分析:只需求 n 的平方根,时间复杂度是 O(1)。
C++ 代码
class Solution {
public:
int bulbSwitch(int n) {
return sqrt(n);
}
};
为什么从 1 到 n 中共有 ⌊√n⌋ 个平方数啊
等价于
[1, n]
区间范围内完全平方数的平方根的数量,比如n
等于25
,1~25
之间的完全平方数的个数不就是1^2,2^2,....sqrt(n)^2
明白了,谢谢大佬
谢谢大佬