前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一道让我怀疑人生的题

一道让我怀疑人生的题

作者头像
写代码的阿宗
发布2020-08-24 11:02:13
3150
发布2020-08-24 11:02:13
举报
文章被收录于专栏:一道题做一宿一道题做一宿

之前经常有人说刚开始刷题时会怀疑人生,觉得每道题都很难,问这正不正常。其实这是正常的,算法本来就是诸多智慧的结晶,何况能拿出来面试的题目都不容易,哪有人万事通,总有我们从未解决过的难题出现,今天我还随机到了一道让我做到怀疑人生的题。

题目是这样的:初始时有 n 个灯泡关闭。第 1 轮,你打开所有的灯泡。第 2 轮,每两个灯泡你关闭一次。第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭)。第 i 轮,每 i 个灯泡切换一次开关。对于第 n 轮,你只切换最后一个灯泡的开关。找出 n 轮后有多少个亮着的灯泡。

这题目乍一看,很简单呀,我套一下循环就能做出来,后期再看怎么优化:

代码语言:javascript
复制
public int bulbSwitch(int n) {
        int result = 0;
        int [] arr = new int[n];
        for (int i = 0; i < arr.length; i++) {
            arr[i] = 1;
        }
        for (int i = 1; i <= arr.length -1; i++) {
            int times = i +1;//第多少轮
            for (int j = 0; j < arr.length; j++) {
                if ((j+1) %times == 0) {
                    if (arr[j] == 0) {
                        arr[j]=1;
                    }else{
                        arr[j] =0;
                    }
                }
            }
        }

        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == 1) {
                result ++;
            }
        }
        return result;
    }

当我兴高采烈地提交的时候,心想着虽然这种暴力解法不够优雅,没有灵魂在里面,但至少算写出来了吧,等会儿我再慢慢优化,没想到直接超时了!

我这下有点懵了,这道题不满足动态规划的结构,也没有我总结的那些套路中关键的条件,还是说有什么隐藏的信息我没有考虑到,抓耳挠腮两个小时也就过去了,再折腾下去我也想不出解法了。默默地点开了题解,题解短到让人看不懂:

代码语言:javascript
复制
int bulbSwitch(int n)
{ 
    return (int)sqrt(n);
}

这是个什么意思,求平方根?这代码的每一个单词我都认识,代码的功能我也都明白,可是它是怎么解答这个问题的呢?

我又默默点开了大神们的讨论,他们有条不紊的分析,一个个的数学公式,一个个的“显而易见”让我头皮发麻,觉得受到了降维打击,虽然咱智商比不过大神们,还是硬着头皮逼着自己去理解他们的思路。

首先,我们得知道判断灯泡是开还是关的方法,将包含本轮在内的对第i个灯泡的所有操作次数做和,若为奇数,说明第i个灯泡,经过j轮以后,是亮着的,因为第0轮一定是关闭的。同理,若为偶数,说明第i个灯泡,经过j轮以后,是关闭的。所以我们的问题也就转换成了,经过n轮,第i个灯泡被操作了奇数次还是偶数次?奇数次则最后是亮的,偶数次则最后是关闭的。

那么如何计算操作的次数呢?这看起来是个大活儿啊。我们再来观察一下:第1个灯泡在什么时候会被操作?第1轮。第10个灯泡在什么时候会被操作?第1轮,第2轮,第5轮,第10轮。第20个灯泡在什么时候会被操作?第1轮,第2轮,第4轮,第5轮,第10轮,第20轮。我们可以发现,第 i 个灯泡只有在第 k 轮会被操作,而 k 一定是 i 的因数。并且 n>=k。所以如果一个数的因数的个数为奇数个,那么它最后一定是亮的,否则是关闭的。

这时候我们的问题已经转换成,什么数的因数的个数是奇数个?回答是完全平方数。为什么它的因数就是奇数个呢?设P,A,B 为正整数,如果 P=A*B,则A和B为P的因数。P的因数A和B总是成对出现。也就是说他们总是一起为 P 的因数个数做贡献,为2。但是如果他们相等呢?这个时候他们一起只会为因数的个数贡献 1。

所以正解就是求平方根了。

看到这里相信好多同学也觉得智商被压制了。没关系,想告诉大家的是觉得刷题吃力也不要有压力,都是这么熬过来的,没有什么路是一直轻松的,跟我一样厚着脸皮看题解就好了嘛。学到了总结出经验了就是自己的,这种需要大量经验跟智商的题做不出来也没什么丢人的嘛(自我洗脑中),前路漫漫,大家共勉。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 写代码的阿宗 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档