jz065.不用加减乘除做加法

 

题目链接

既然不能用加减乘除,我们可以考虑位运算,对于十进制的加法来说,一般有两个步骤,一是在不产生进位的情况下将同一位的数字加在一起,二是在产生进位的情况下将进位加到相对更高的位去。对于二进制的位运算来说,我们可以用异或运算实现不带进位的加法,用和运算加上左移一位实现进位。但是,我们注意到,每次进行和运算然后左移操作时最多只能将后一位的进位处理掉,在进位过程中会产生类似一次性进两位甚至更多为的情况,循环可以用来处理这种情况,并且循环终止的条件是进位为0。另外,由于python中负数的存储机制,我们对于负数要先对32位以上的数字取反获取负数的补码才能进行运算,为了保证左移过程中不出现差错(会有位数被移动到高于32位),我们也对左移后的结果求补码。最后在输出答案时,我们也先判断数字是否为负数然后按情况返回。这个算法的时间复杂度因为最多循环32次所以是O(1),空间复杂度因为只有32位所以是O(1)。

class Solution:
    def add(self, a: int, b: int) -> int:
        x = 0xffffffff
        a, b = a & x, b & x
        while b != 0:
            a, b = (a ^ b), ((a & b) << 1) & x
        return a if a <= 0x7fffffff else ~(a ^ x)