LeetCode-两整数之和

516 阅读3分钟

不使用运算符 +- ,计算两整数 ab 之和。

题目说不能使用运算符 + 和 -,那么可以使用其他方式来替代两个运算符的功能。

位运算

我们平常开发中位运算使用的并不多,但如果能巧妙使用位运算可以减少运行开销和优化算法,比如Java源码里面的HashMap就有位运算。

单位换算

  1. bit:位。一个二进制数据0或1,是1bit

  2. byte:字节。1 byte = 8 bit,存储空间的计量单位

  3. 一个英文字符占一个字节。

  4. 一个汉字占两个字节。

支持的数据类型

首先明确一点,Java中的位运算是针对整形的数据类型进行运算的,所以操作数必须是以下五种之一:byte、short、int、long、char

位运算符

&按位与
|按位或
~按位非
^按位异或
<<左移
>>右移
<<<无符号右移

按位与 &

操作十进制二进制
操作数130 0 1 1
操作数250 1 0 1
& 后结果10 0 0 1

总结:对应位同为1,才为1,否则全为0。

另外:你可以把1理解为true,把0理解为false, true和false进行与(&)时,必须同为true时结果才为true。

按位或 |

操作十进制二进制
操作数130 0 1 1
操作数250 1 0 1
| 后结果70 1 1 1

总结:对应位只要有1时,即为1,否则全为0(对应位只有全是0时,结果才是0,否则为1)。

另外:你可以把1理解为true,把0理解为false, true和false进行或(|)时,只要有true,结果即为true。

按位非 ~

操作十进制二进制
操作数130 0 1 1
~ 后结果121 1 0 0

总结:对每位进行取反。

按位异或 ^

操作十进制二进制
操作数130 0 1 1
操作数250 1 0 1
^ 后结果70 1 1 0

总结:只要对应为不同即为1。

左移 << 和 右移 >>

m<<n即在数字没有溢出的前提下,对于正数和负数,左移n位都相当于m乘以2的n次方。

m>>n即相当于m除以2的n次方,得到的为整数时,即为结果。如果结果为小数,此时会出现两种情况:

  1. 如果m为正数,得到的商会无条件 的舍弃小数位;

  2. 如果m为负数,舍弃小数部分,然后把整数部分加+1得到位移后的值。

无符号右移 >>>

无符号右移>>> 与 右移>> 的区别就是无论操作数是正数还是负数,高位都是补0。

恩,基础知识暂时讲解这么多,下面回归本题加法实现。

加法实现

对于二进制的整数加法来说,我们需要让 1 和 0 的运算结果为 1,而 0 和 0的运算结果为 0。这和 异或 运算的结果刚好相同。

 1 ^ 0 = 1, 0 ^ 0 = 0

同时,我们需要让 1 和 1的运算结果为 10,也就是需要进位,很明显无法使用单次的位运算操作实现,因为我们可以考虑通过 运算和 移位 运算来实现。

(1 & 1) << 1 = 10

和竖式加法一样,如果两个数相加不发生进位,那么直接用 异或 就足够了,如果发生进位,那么我们需要将 异或 的结果和 进位 的结果相加。

java 代码实现

public int getSum(int a, int b) {       
 int sum = a, carry = b;        
 while (carry != 0) {           
    int temp = sum ^ carry;            
    carry = (sum&carry)<<1;            
    sum = temp;       
  }        
  return sum;    
}

如果觉得写的不错,求关注、求点赞、求转发,如果有问题或者文中有错误,欢迎留言讨论。

转载请注明出处。

扫描关注公众号,第一时间获得更新