每日一题算法:2020年6月2日 面试题64. 求1+2+…+n sumNums

2020年6月2日 面试题64. 求1+2+…+n sumNums

每日一题算法:2020年6月2日 面试题64. 求1+2+…+n sumNums_第1张图片

class Solution {
    public int sumNums(int n) {
    }
}

解题思路:

WTF,这个题目不按套路出牌,感觉像是数学竞赛题一样,不能用乘除法,那么我只能用加减法和逻辑运算。

首先,这个公式我们肯定都知道,首项乘末项乘以项数除以二。

1+2+3+…+n=(1+n)(n)/2

我们把它分解开

(1+n)*n这里有一个乘法,乘法用逻辑运算怎么做,这个有些复杂,慢慢说

首先我们转变思想,十进制的乘法怎么做的,按位运算再求和,所以二进制也是同理的

十进制乘法:

42X35=42X30+42X5=42X3X10+42X5=1260+210=1470

二进制乘法:

12X25= 1100X11001=1100X10000+1100X1000+1100X1

1100左移五次=11000000

1100左移四次=1100000

1100左移0次=1100

相加100101100=256+32+8+4=300=12X25

OK,到此为止就算是完成了二进制的乘法运算的规则学习

那么我们怎么用逻辑运算实现25的拆解和乘法呢?

我们用与运算,11001&10000可以得到 16,

下一个问题,我们如何实现乘法

用位移运算,我们得到的16转变为左移四位的指令,也就是我们怎么把10000变成100

我们需要考虑到两种情况,也就是该位上有数和没有数的情况,因为不能使用if等关键字,所以我们无法对结果进行分类处理,我们的算法必须自动区分开10000和00000

我放弃,我想了很久没有找到解决的办法,我觉得自己的思路有问题,但是却找不到其他的思路来解决这道问题,所以我觉得去看一看答案是怎样的,在理解了答案之后再来写代码。

答案解析:

我看明白了,这是使用了短路与运算法来实现对操作的选择。

 flag = ((B & 1) > 0) && (ans += A) > 0;

这句话中flag=和>0这都是为了让代码符合逻辑而添加上的

实际上我们只需要关注((B&1)>0)&&(ans+=A)中间的&&符号,他的含义是,如果左边成立,那就判断右边是否成立,如果左边不成立,那就直接跳过右边的判断。

那么将其结合到我的代码中。并且同时可以对源代码进行优化,不用将值进行转换了,直接将其位移就可以了,因为我们只需要判断是否大于0就可以判断出是否需要位移。`
每日一题算法:2020年6月2日 面试题64. 求1+2+…+n sumNums_第2张图片

        //第一位到第14位的数字
        int n1=n&1;
        int n2=n&2;
        int n3=n&4;
        int n4=n&8;
        int n5=n&16;
        int n6=n&32;
        int n7=n&64;
        int n8=n&128;
        int n9=n&256;
        int n10=n&512;
        int n11=n&1024;
        int n12=n&2048;
        int n13=n&4096;
        int n14=n&8192;
        int res=0;
        boolean util=true;

        //下面的14次循环表示开平方
        util=(n1>0)&&((res+=n)>0);
        util=(n2>0)&&((res+=n<<1)>0);
        util=(n3>0)&&((res+=n<<2)>0);
        util=(n4>0)&&((res+=n<<3)>0);
        util=(n5>0)&&((res+=n<<4)>0);
        util=(n6>0)&&((res+=n<<5)>0);
        util=(n7>0)&&((res+=n<<6)>0);
        util=(n8>0)&&((res+=n<<7)>0);
        util=(n9>0)&&((res+=n<<8)>0);
        util=(n10>0)&&((res+=n<<9)>0);
        util=(n11>0)&&((res+=n<<10)>0);
        util=(n12>0)&&((res+=n<<11)>0);
        util=(n13>0)&&((res+=n<<12)>0);
        util=(n14>0)&&((res+=n<<13)>0);


        //公式的变式为(n^2+n)/2=(n^2)/2+n/2
        return (res+n)>>1;

总结:这道题的考点在于四个地方

1,逻辑运算操作的熟练度

2,使用短路逻辑运算符控制代码执行顺序的概念

3,用有限循环代替无限循环执行限定值的公式

4,脑子好不好,思维是不是够跳跃。

最后的最后,我只想说,如果哪家公司出这种面试题,我绝对直接拍屁股走人,除非加钱。

你可能感兴趣的:(每日一题算法,算法,java,数据结构)