LeetCode 672. Bulb Switcher II

本文探讨了一个涉及灯状态变化的问题,通过分析按钮操作及其对灯状态的影响,总结出了一个高效的算法来计算不同操作次数下灯的所有可能状态数目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.题目房间里有n盏灯,初始时全是亮的,房间的墙上有4个按钮。问在按了恰好m次按钮后,n盏灯的状态共有多少种可能,返回这个值。

 

n盏灯的标号[1,2,3,……,n]4个按钮的功能如下:

i.反转所有灯的状态。

ii.反转所有偶数标号的灯的状态。

iii.反转所有奇数标号的灯的状态。

iv.反转所有形如(3*k+1)标号的灯的状态,k=0,1,2,……。:房间里有n盏灯,初始时全是亮的,房间的墙上有4个按钮。问在按了恰好m次按钮后,n盏灯的状态共有多少种可能,返回这个值。

n盏灯的标号[1,2,3,……,n]4个按钮的功能如下:

    i.反转所有灯的状态。

    ii.反转所有偶数标号的灯的状态。

    iii.反转所有奇数标号的灯的状态。

    iv.反转所有形如(3*k+1)标号的灯的状态,k=0,1,2,……。

2. 考虑周期性:假设灯足够多,如果只有按钮1,至多两种可能:全灭或者全亮;如果按钮2和按钮3考虑进来的话,最后灯的状态就是以2为周期的;如果把按钮4考虑进来的话最后灯的状态是以6为周期的,因为按钮4是(3*k+1)。

3. 按钮的按的顺序可以交换不改变结果;同一个按钮状态跟按的奇偶次有关;按钮1、按钮2、按钮3其中两个是可以替代另一个的,也就是说按这三个中的任意两个等于按下另一个,四个按钮中有效的也就是三个,三个按钮各自按和不按两种情况,最多有8种状态。

4.  m =3时,m = 4 时这8种状态都是可以实现的,m>=5的情况只要从m = 3 或者m = 4的情况对某个灯增加按偶数次即可得到。

5. 用一个二进制的数来表示灯的状态,灯的状态以6位周期,所以只看6位。初始状态为000000,按一次按钮1变为111111;按一次按钮2变为010101;按一次按钮3变为101010;按一次按钮4变为100100

6. m = 1时,按一次开关有四种可能111111010101101010100100,如果n = 1,就看第一位,只有10两种可能。如果n = 2看前两位,11,01,10三种,如果n >=3 那么就有四种可能。

7. m = 2时,按两次开关有4^2=16种可能,但是不同的状态有7种:000000001110010101011011101010110001111111。如果n=1,看第一位,有01两种可能。如果n=2,看前两位,有00011011四种可能;如果n>=3,所有7种可能都互不相同。

8. m>=3时,总共有8种不同可能:000000001110010101011011100100101010110001111111。如果n=1,可以只看第1位,有01两种可能;如果n=2,看前两位,有00011011四种可能;如果n>=3,所有8种可能都互不相同。


class Solution {
    public int flipLights(int n, int m) {
   /*   方法1 :直观写法 
        if(m == 0){
            return 1;
        }
        if(m == 1){
            if(n == 1){
                return 2;
            }else if(n == 2){
                return 3;
            }else{
                return 4;
            }
        }else if(m == 2){
            if(n == 1){
                return 2;
            }else if(n == 2){
                return 4;
            }else{
                return 7;
            }
        }else{
            if(n == 1){
                return 2;
            }else if(n == 2){
                return 4;
            }else{
                return 8;
            }
        }
        
        */    
    /*
    方法2:优化写法
    */
        if(m == 1){
            if(n == 2){
                return 3;
            }
            return Math.min(4,1<<n);
        }
        if(m == 2){
            return Math.min(7,1<<n);
        }
        return Math.min(8,1<<Math.min(m,n));
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值