2020年6月2日 面试题64. 求1+2+…+n sumNums
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就可以判断出是否需要位移。`
//第一位到第14位的数字
int n1=n&1;
int n2=n&2;
int n3=n