LeetCode 371: Sum of Two Integers 题解

本文介绍了一种特殊的算法,即在不使用加号(+)和减号(-)的情况下计算两个整数的和。文章详细解析了如何利用位运算实现这一目标,并提供了具体的实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原题如下:

LeetCode 371: Sum of Two Integers

Problem:
Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.


Example:
Given a = 1 and b = 2, return 3.


题的意思是计算两个整数的和,但是不能用加号(+)和减号(-),当然也不能用:+=、-=、++、–了,既然不能用加减来做运算,那乘除运算能求两个数的和吗,显然是不能的,除非遇到两个数相等,或者其中一个等于0等特殊情况,但是这道题要求对任意两个数字求和,那么加减乘除都不能做到这一点,自然能想到只能通过位运算来达到目的了。

首先,有关的运算包括:按位与(&)、按位或(|)、按位异或(^)、移位。那么要如何用这些运算计算两个数的和呢。下面来看个例子。

假设有两个数 a = 0010, b = 0011,我们可以知道:
1) a & b = 0010
2) a | b = 0011
3) a ^ b = 0001
其中与运算将对应的位均为1的位表示了出来(在这里是第2位),这就表示该位要进位,它的下一位(在这里是第三位)需要加上1。亦或将所有的对应位不相同的位表示了出来(在这里只有第一位),这就表示如果所有的位都没有进位的话,那么这个亦或的值就是答案,因为二进制的加法如果不考虑进位的话,就等价于两个二进制数相亦或。而或运算在这里的用处不大,因为加法的两个步骤:相加和进位已经分别被亦或运算和与运算实现了。那么现在来看看具体步骤:

首先,令 x=a & b = 0010 表示第三位需要加一;令 ans = a ^ b = 0001,表示不考虑进位的话,答案就为0001。我们先将 x 左移一位得到 x = 0100,表示第三位需要加上1。这时,令 ans ^= x = 0101,得到一个没有考虑进位的答案,然后在来看看第一次进位之后还需不需要再进位:x &= ans = 0000,表示第一次进位之后就不需要进位了。那么 a+b = 0101。

要点就在于,与运算能够判断下一位是否需要加1,而亦或运算能够算出舍弃了进位的答案,那么如果循环执行这个流程,那么就能处理掉所有的进位。理解的最好办法就是再纸上多试试。

通过的代码如下:

int getSum(int a, int b) {
    int shift = a & b;      //找出需要进位的位
    int ans = a ^ b;        //得到不带进位的答案
    while(shift){
        shift <<= 1;        //将进位标志左移一位
        int pre_ans = ans;  //记录之前的亦或值
        ans ^= shift;       //得到新的不带进位的答案
        shift &= pre_ans;   //找出还需要进位的位
    }
    return ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值