【字符串】【打卡79天】leetCode每日一题:319. 灯泡开关

1、题目描述

初始时有 n 个灯泡处于关闭状态。第一轮,你将会打开所有灯泡。接下来的第二轮,你将会每两个灯泡关闭一个。

第三轮,你每三个灯泡就切换一个灯泡的开关(即,打开变关闭,关闭变打开)。第 i 轮,你每 i 个灯泡就切换一个灯泡的开关。直到第 n 轮,你只需要切换最后一个灯泡的开关。

找出并返回 n 轮后有多少个亮着的灯泡。

2、算法分析

1、常规方法:

定义一个boolean的数组,true代表灯亮的,false表示熄灭。默认全是亮着的。

每间隔i个就切换开关。可以使用两个for循环控制。

最后统计数组中为true的个数。

但是最后有一个999999这个用例过不去。有点可惜。

2、比较吊的方法,就一行代码,数学推理。也好理解。

知识补充:什么是因子?

假如整数n除以m,结果是无余数的整数,那么我们称m就是n的因子。因子是整数中的概念。一个整数n的因子数为包含它自身的所有因子个数。例如,12的因子数为6(1,2,3,4,6,12)。

初始有n个灯泡关闭。第i轮的操作是每i个灯泡切换一次开关(开->闭,闭->开),即切换i的倍数位置的开关。
求n轮后亮着的灯泡?
(1)第i轮时,被切换的灯泡位置是i的倍数。
(2)由(1)得出,对于第p个灯泡来说,只有其第“因子”轮才会切换,若其有q个因子,则最终被切换q次。因为初始状态是关闭状态,那么因子数是奇数的灯泡最终是亮着的。
(3)只有平方数的因子个数不是成对出现,举例:4=1*4,2*2,其因子是1,2,4。
(4)那么题目最终转化为1~n里平方数的个数,进而转化为对n开平方根,向下取整即可。

3、代码实现

常规方法:

class Solution {
    public int bulbSwitch(int n) {
        if(n == 0){
            return 0;
        }
        int resCount = 0;
        boolean[] light = new boolean[n + 1];
        Arrays.fill(light,true);
        // 从第二个开始
        for(int i = 2;i <= n;i++){
            // 间隔着开关
            for(int j = i;j <= n;j += i){
                light[j] = !light[j];
            }
        }
        // 计数
        for(int i = 1;i <= n;i++){
            if(light[i]){
                resCount++;
            }
        }
        return resCount;
    }
}

数学推理:

import java.util.*;
class Solution {
    public int bulbSwitch(int n) {
        // 取平方根
       return (int) Math.floor(Math.sqrt(n));
    }
}

猜你喜欢

转载自blog.csdn.net/Sunshineoe/article/details/121328165