LeetCode_319灯泡开关

初始时有 n 个灯泡关闭。 第 1 轮,你打开所有的灯泡。 第 2 轮,每两个灯泡你关闭一次。 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭)。第 i 轮,每 i 个灯泡切换一次开关。 对于第 n 轮,你只切换最后一个灯泡的开关。 找出 n 轮后有多少个亮着的灯泡。
LeetCode_319灯泡开关_第1张图片
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bulb-switcher
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

class Solution {
    /*
    首先思考:灯泡i会被按几次?这其实相当于求i有几个因子
    一开始灯都是灭的,所以如果i有k个因子,且k为奇数,那么最终灯就亮,如果为偶数,灯就灭。 
    那么问题就转化成了,求1..n每个数分别有几个因子。 最直观的做法就是,枚举i,然后计算i的因子数。

    在写完上面的式子之后你突然可以发现,在根号i的左边每发现一个j使得i%j==0,那么根号i的右边一定存在一个k同样满足i%k==0,
    一次枚举会把count+2。而我们关心的其实是最终count为奇数还是偶数!!
    通过枚举,count最终的结果都是偶数,当且仅当 i可以被开根号时,count才会是奇数!

    然后其实问题转换成了,求数字1..n中有几个数能开更开得尽(结果是整数)

    想到这里,你就可以一个O(n)的枚举来完成了吗? 其实还可以优化!

    想想,在1..n中,假设n等于100,1*1 2*2 3*3 4*4 ... 10*10的结果都小于等于100,换句话说,1*1 ... 根号n*根号n 都<= n,
    所以求1..n里有几个开根号能开尽的数,其实就是求根号n向下取整等于几。
    */
    public int bulbSwitch(int n) {
        return (int)Math.sqrt(n);
    }
}

你可能感兴趣的:(LeetCode题解)