【Leetcode】:319. Bulb Switcher 问题 in JAVA

本文通过分析灯泡开关问题的规律,发现最终灯泡是否亮起取决于其编号为平方数的特点。并给出了简洁高效的求解算法。

There are n bulbs that are initially off. You first turn on all the bulbs. Then, you turn off every second bulb. On the third round, you toggle every third bulb (turning on if it's off or turning off if it's on). For the ith round, you toggle every i bulb. For the nth round, you only toggle the last bulb. Find how many bulbs are on after n rounds.

举例:Given n = 3. 

At first, the three bulbs are [off, off, off].

 After first round, the three bulbs are [on, on, on]. 

After second round, the three bulbs are [on, off, on]. 

After third round, the three bulbs are [on, off, off].

-----------------------------------------------------------------------------------------------------------------------------

先尝试模拟整个过程来得到结果,提交超时了,看来不行

public class Solution {
    public int bulbSwitch(int n) {
        boolean[] b = new boolean[n];
        for (int i = 0; i < n; i++){
            for (int j = i; j < n; ) {
                b[j] = !b[j];
                j += i + 1;
            }
        }
        int sum = 0;
        for (int i = 0; i < n; i++) {
            if (b[i] == true) {
                sum += 1;
            }
        }
        return sum;
    }
}

-----------------------------------------------------------------------------------------------------------------------------

那只有来分析规律了,先看看n=10的情况,并不需要模拟整个过程,只需要观察每个灯被翻转的次数即可

灯       号:1  2  3  4  5  6  7  8  9  10

翻转次数:1  2  2  3  2  4  2  4  3  4

可以看出最后只有翻转了奇数次的灯1 4 9会亮,1 4 9全都是平方数,很好,有规律。

9会亮3次是因为在第1次翻转,第3次翻转,还有第9次翻转都翻转了9,可以看出,一个数字被翻转的次数就是他的因子的个数,如果最后是亮着的状态,那么它的因子的个数必须为奇数。结合前面平方数的规律,如果一个数是平方数,那么它的因子个数一定是奇数,那么问题就解决了。


public class Solution {
    public int bulbSwitch(int n) {
        int sum = 0;
        for (int i = 1; ; i++) {
            if (i*i > n) {
                break;
            }
            sum++;
        }
        return sum;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值