【每日算法Day 66】经典面试题:不用四则运算如何做加法?

题目链接

LeetCode 面试题65. 不用加减乘除做加法[1]

题目描述

写一个函数,求两个整数之和,要求在函数体内不得使用 +,-,*,/ 四则运算符号。

示例1

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

      

提示

  • a, b 均可能是负数或 0
  • 结果不会溢出 32 位整数

题解

因为不允许采用四则运算,所以只能考虑位运算了。

其实就是用二进制来模拟加法操作。首先将两个数最低位相加,如果都是 1 ,那么就得到 0 ,并且进位 1 ,然后接着算下一位。

但是这样一位一位模拟不方便实现,更简单的实现方法是直接把两个数对应位相加,不管进位。然后进位单独计算,如果某一位两个数都是 1 ,那么进位就会对下一位产生影响。然后接着算不进位求和加上进位的值,再计算新的进位,依次重复下去,直到进位为 0 为止。

用一个实际的例子来演示一下,计算 3+7 的值,其中 s 表示每一步不考虑进位的求和,c 表示每一步的进位,最后得到结果 1010 ,也就是十进制的 10

v2-dda6c0afd1c267f6f0ebaf8e8dd0c82f_b.jpg


但是这里还是用到了加法怎么办呢?因为是二进制,所以不考虑进位求和的话,可以直接采用异或运算。而计算进位的话,直接用位与左移一位就行了。

在 c++ 和 python 具体实现中,还有几个注意事项:

  • LeetCode c++ 不允许负数左移操作,所以要转换成无符号整数。
  • python 因为位数没有限制,所以负数补码会很长,所以要位与 0xffffffff 处理成 32 位整型数。
  • c++ 还可以写成递归形式,也就是 a+b 可以递归成 s+c ,其中 s 表示不进位求和结果,c 表示进位的值。

代码

非递归(c++)

        class Solution {
public:
    int add(int a, int b) {
        while (b) {
            int carry = (unsigned int)(a & b) << 1;
            a ^= b;
            b = carry;
        }
        return a;
    }
};

      

递归(c++)

        class Solution {
public:
    int add(int a, int b) {
        return b ? add(a^b, (unsigned int)(a&b)<<1) : a;
    }
};

      

非递归(python)

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

      

投机取巧(python)

        class Solution:
    def add(self, a: int, b: int) -> int:
        return sum([a, b])

      

参考资料

[1]

LeetCode 面试题65. 不用加减乘除做加法: leetcode-cn.com/problem

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

算法码上来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值