[LeetCode] 371. Sum of Two Integers

版权声明:如需转载请注明出处 https://blog.csdn.net/Bertram03/article/details/86840630

原题链接: https://leetcode.com/problems/sum-of-two-integers/

1. 题目介绍

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

Example 1:
Input: a = 1, b = 2
Output: 3

Example 2:
Input: a = -2, b = 3
Output: 1

不使用 + 和 - 来计算两个数的和。
这里我介绍一下利用位操作来完成两个数的加法、减法、求负数的计算。

2. 加法

不能用加减运算符,那就使用位运算来计算和。

我们平时使用加法运算时,是先计算低位,后计算高位。低位相加后会产生进位,高位相加时,需要把低位的进位加进来一起运算。

比如,7+10 = 17,利用二进制计算就是0111+1010=10001
在这里插入图片描述
现在我们能不能把两部分分开呢?
不考虑进位的加:
0111+1010 = 1101
在这里插入图片描述
只考虑进位,把进位的数位置1:
0111+1010 = 0010
在这里插入图片描述
现在,把进位的部分左移一位,然后加上不进位的加法,就可以得到和了。
0010左移一位变成0100,0100+1101 = 10001 = 17(十进制)

不考虑进位的那部分,0+0=0,0+1=1,1+0=1,1+1=0,这就是异或 ^ 的运算规则;
只考虑进位的那部分,0+0=0,0+1=0,1+0=0,1+1=1,这就是与 & 的运算规则。

于是我们可以得出,替代a+b 的方法就是,首先计算 a^b,然后 a&b 左移1位,最后再把两者加起来,可以用递归或者循环来实现。结束递归或者循环的条件是进位为零。

递归实现

扫描二维码关注公众号,回复: 5286797 查看本文章
class Solution {
   public int getSum(int a, int b) {
        if(b==0) return a;
        int x = a ^ b;
        int y = (a & b)<<1 ;
        return getSum(x , y);        
    }
}

循环实现

class Solution {
   public int getSum(int a, int b) {
       while(b != 0) {
    	   int Carry = a & b;
    	   a = a ^ b;
    	   b = Carry<<1;
       }
       return a;
    }
}

3. 计算差

在计算机中,计算 a-b 可以转化为 a +(-b),而-b的就是b的反码+1,也即 ~b+1。
所以 a - b = a +( ~b+1 )

public int getSubtract(int a, int b) {
	   b = ~b+1;
       while(b != 0) {
    	   int Carry = a & b;
    	   a = a ^ b;
    	   b = Carry<<1;
       }
       return a;
    }

或者

public int getSubtract(int a, int b) {
	while (b != 0) {
		int borrow = (~a) & b;
		a = a ^ b;
		b = borrow << 1;
	}
	
	return a;
}

4. 求负数

-b = ~b +1

public int negate(int x) {
	return ~x + 1;
}

5. 参考链接

https://leetcode.com/problems/sum-of-two-integers/discuss/84290/Java-simple-easy-understand-solution-with-explanation
https://www.cnblogs.com/grandyang/p/5631814.html

猜你喜欢

转载自blog.csdn.net/Bertram03/article/details/86840630
今日推荐