【日常训练】剑指 Offer 65. 不用加减乘除做加法

题目描述:

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

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

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

代码:

/**
 * @author :Puppet
 * @description:剑指offer 65
 * @date :2021/11/11 10:52
 */
public class NumAdd {

    /**
     * 位运算:时间复杂度O(n) 空间复杂度O(1)
     * 我们可以将其改为二进制进行计算,注意计算机中都是存储的数字的补码。
     * 我们不难发现,通过二进制进行加法操作会出现两种情况:(1)不需要进位  (2)需要进位
     * 两个数相加的值 a + b = 不需要进位的值n + 进位的值k,所以接下来主要是找到求n和k的方法
     * (1)不需要进位:就是异或操作 a^b
     * (2)需要进位:只有当该位置上两个数的值都为1时,才会发生进位,我们可以通过&操作得到该两个数为1的位置,我们将其左移一位,这样就得到了进位后的值,我们得到公式如下:(a&b)<<1
     *  我们11和9为例:
     *  第一轮:(1011 & 1001) << 1 = 1001 << 1 = 10010  1011^1001 = 0010  => a=0010 b=10010
     *  第二轮:=> c = (0010 & 10010) << 1 = 00010 << 1 = 000100  => a = 10000 b = 000100
     *  第三轮:=> c = 0 => a = 10100(16) b= 0
     *
     *  所以我们可以得出算法,将a+b 拆分成多个进位k和不进位n相加的情况,没位可进时,结束该循环。
     *
     */
    public int add(int a, int b) {
        while (b != 0){
            int c = (a&b)<<1;
            a ^= b;
            b = c;
        }
        return a;
    }

    public static void main(String[] args) {
        NumAdd numAdd = new NumAdd();
        System.out.println(numAdd.add(1, 1));
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值