「每日一题」两整数之和

285 阅读1分钟

这是 LeetCode 上 2021-9-26 的每日一题:「371. 两整数之和」

1. 题目描述

给你两个整数 ab不使用 运算符 +- ,计算并返回两整数之和。

示例:

输入:a = 1, b = 2
输出:3

2. 解答

对于位运算中的加法,只有四种情况:

0 + 0 = 0
0 + 1 = 1
1 + 0 = 1
1 + 1 = 0(进位 1

总结规律可得,对于ab,不考虑进位的加法 = a^b

例如,对于a=2b=3

a = 0010
b = 0011

a ^ b:

0 0 1 0
0 0 1 1
-------
0 0 0 1

在位运算中,进位可以有得到:

a = 0010
b = 0011

a & b:

0 0 1 0
0 0 1 1
-------
0 0 1 0

得到的0010并不是真正的进位,进位1需要在更高一位上,故左移一位即可得到0100

那么将不考虑进位的加法加上进位即可得到结果:

0 0 0 1
0 1 0 0
-------
0 1 0 1       (5)

若相加后还有进位的话,将a^b的结果与进位继续进行上述操作,直到没有进位为止。

总结一下,对于给定的ab

  • 不考虑进位的加法:a^b
  • 进位:(a & b) << 1

那么不断地将进位再次与不考虑进位的加法结果作相同的运算,直到进位为0即可。

容易写出以下代码。

1. 迭代

const getSum = (a, b) => {
    while (b) {
        // 进位
        const c = (a & b) << 1;
        // 不考虑进位的加法
        a ^= b;
        // 将进位赋值给b
        b = c;
    }
    return a;
};

2. 递归

也可以用递归实现:

const getSum = (a, b) => {
    if (!b) return a;
    return getSum(a ^ b, (a & b) << 1);
};

简单一点也可以:

const getSum = (a, b) => (b ? getSum(a ^ b, (a & b) << 1) : a);

😄最近新创建了个开源仓库,总结 LeetCode 的每日一题,目前已有 C++、JavaScript 语言版本,欢迎大家提供其他语言版本!

🖥️仓库地址:「每日一题系列」