mirror of
https://github.com/ShusenTang/LeetCode.git
synced 2024-09-02 14:20:01 +00:00
Create 319. Bulb Switcher.md
This commit is contained in:
parent
07640218f8
commit
af03087cdd
55
solutions/319. Bulb Switcher.md
Normal file
55
solutions/319. Bulb Switcher.md
Normal file
@ -0,0 +1,55 @@
|
||||
# [319. Bulb Switcher](https://leetcode.com/problems/bulb-switcher/)
|
||||
|
||||
# 思路
|
||||
有n个初始全灭的灯泡,第一次更改所有灯泡的状态(即全部打开),第二次更改2、4...灯泡的状态,第三次更改第3、6...灯泡的状态,以此类推,第n次更改第n个更改灯泡的状态。然我们求最后亮灯泡的个数。
|
||||
|
||||
由题意可知,某个灯泡最后的状态取决于它被更改了多少次,如果被更改了偶数次那么就回到初始灭态,若被更改了奇数次就是亮态。
|
||||
那么第i个灯泡被更改了多少次呢?由题意分析可知被更改了dp[i]次,dp[i]代表i的所有因数个数。那如何求1-n共n个数的各自的因数个数呢?
|
||||
我们知道,若`m*n = k`,那么m和n都是k的因数(注意考虑m是否等于n),所以我们可以写一个二重循环来不断更新dp:
|
||||
```
|
||||
for i in [1, sqrt(n)]:
|
||||
for j in [i, n/i]:
|
||||
dp[i*j] += (i == j ? 1:2)
|
||||
```
|
||||
因此最后的完整代码就为:
|
||||
``` C++
|
||||
class Solution {
|
||||
public:
|
||||
int bulbSwitch(int n) {
|
||||
vector<int>dp(n+1, 0);
|
||||
int res = 0;
|
||||
for(int i = 1; i <= int(sqrt(n)); i++){
|
||||
for(int j = i; j <= n / i; j++)
|
||||
dp[j*i] += (i == j ? 1:2);
|
||||
|
||||
res += (dp[i] % 2);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
稍加分析上述代码可以发现:在第二重循环中若`i != j`时会增加两个因数,但是我们最后会对因数对2取模,也就是说其实是不用考虑`i != j`情况的,
|
||||
则循环代码就变成
|
||||
``` C++
|
||||
for(int i = 1; i <= int(sqrt(n)); i++){
|
||||
dp[i*i] += 1;
|
||||
res += (dp[i*i] % 2); // 即 res += 1
|
||||
}
|
||||
```
|
||||
|
||||
> 直观上也很好理解,若k不是平方数,对于任意k的因数m,一定能找到唯一的`n = k/m`也是k的因数,其中`m != n`,因此k的因数个数一定是偶数。
|
||||
|
||||
也就是说求1-n有多少个平方数,那我们直接返回`sqrt(n)`就可以了,所以最后的代码很简单,如下。
|
||||
|
||||
|
||||
# C++
|
||||
``` C++
|
||||
class Solution {
|
||||
public:
|
||||
int bulbSwitch(int n) {
|
||||
return sqrt(n);
|
||||
}
|
||||
};
|
||||
```
|
Loading…
Reference in New Issue
Block a user