剑指 Offer 65. 不用加减乘除做加法
写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。
示例:
输入: a = 1, b = 1
输出: 2
提示:
a, b 均可能是负数或 0
结果不会溢出 32 位整数
通过次数67,847提交次数116,612
只用看题目就能知道,本题的考点是位运算,毕竟位运算的效率要比数值运算和逻辑运算高很多,以下是分析:
在做加法时,如果一个是 1,另一个是 0,那么加的结果是 1,如果两个都为 0,那么加的结果是 0,如果都是 1,那么加的结果也是零,只不过会有进位,单从加的结果来看,其实就是异或运算,相同为 0,不同为 1,因为我们想到用异或来算加位,那么进位怎么算呢,只有两个数都是 1 的时候才会产生进位,其实就是逻辑与运算,再将进位的结果与加位的结果异或就能得出答案,图解如下:
c 是进位,第一次循环 a 变为与 b 异或的结果,b 变为 c,如图:
再一次异或,即可求出结果:
class Solution {
public int add(int a, int b) {
// b 作为进位,a 作为最后的结果
while (b != 0) { // 不产生进位的时候,说明加完了,此时退出循环
int c = (a & b) << 1;
a ^= b;
b = c;
}
return a;
}
}
一个月以后的复盘:
都知道其实加法运算其实就是把 异或 的结果再加上 进位的结果,通过循环体,先求进位,然后异或求异或结果,然后让 b 等于 进位的结果,如此循环,再次异或就是相加一次的结果,直到不再产生进位为为止(也就是 b == 0)的时候结束。
class Solution {
public int add(int a, int b) {
while (b != 0) {
int c = (a & b) << 1;
a = a ^ b;
b = c;
}
return a;
}
}