leetcode371. 两整数之和
给你两个整数 a 和 b ,不使用 运算符 + 和 - ,计算并返回两整数之和。
示例 1:
输入:a = 1, b = 2
输出:3
示例 2:
输入:a = 2, b = 3
输出:5
提示:
-1000 <= a, b <= 1000
题目分析
实现一个函数,计算两个整数 a
和 b
的和,但不允许使用加法运算符 +
和减法运算符 -
。这个问题可以通过位运算来解决,利用异或运算符 ^
和与运算符 &
来实现加法。
算法思路的深入探讨
这个问题的核心在于如何通过位运算实现加法。这实际上与计算机中的逻辑电路设计紧密相关。在计算机中,加法是通过一系列的位运算来实现的,特别是异或(XOR)和与(AND)运算。
异或运算(XOR)
异或运算有一个很有趣的性质:任何数与自身进行异或运算,结果都是0;任何数与0进行异或运算,结果都是它本身。这使得异或运算非常适合用来计算不带进位的加法部分。
与运算(AND)和左移(<<)
与运算可以用来找出两个数在对应位上的公共部分,即它们的进位。左移运算则可以将这个进位向左移动一位,为下一次加法运算做准备。
逻辑电路的联系
这种位运算的加法方法与逻辑电路中的半加器和全加器的设计非常相似。半加器能够计算两个输入的加法,但不包括进位;全加器则能够计算两个输入的加法,并包括进位。
算法步骤
- 初始化一个变量
carry
为0,用于存储进位。 - 当
b
不等于0时,进行循环:- 计算
a
和b
的按位与,然后左移一位,得到进位carry
。 - 计算
a
和b
的异或,得到没有进位的和。 - 更新
b
为carry
,a
为没有进位的和。
- 计算
- 返回
a
作为最终结果。
算法流程
具体代码
class Solution {
public:
int getSum(int a, int b) {
while(b!=0)
{
unsigned int carry=((unsigned)(a&b))<<1;
a=a^b;
b=carry;
}
return a;
}
};
算法分析
- 时间复杂度: O(log(max_int)),其中我们将执行位运算视作原子操作。
- 空间复杂度: O(1),因为只需要常数级别的额外空间。
- 易错点: 需要注意整数溢出的问题,特别是在计算进位时,需要将结果转换为无符号整数进行左移。
相似题目
题目 | 链接 |
---|---|
371. 两整数之和 | https://leetcode.cn/problems/sum-of-two-integers/ |
67. 二进制求和 | https://leetcode.cn/problems/add-binary/ |
415. 字符串相加 | https://leetcode.cn/problems/add-strings/ |