剑指 Offer 65. 不用加减乘除做加法

剑指 Offer 65. 不用加减乘除做加法https://leetcode.cn/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/

题目:

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

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

是一道需要我死记硬背的题目了

每次遇到 位运算 的题目,我就无能为力,二进制杀我!!!!

这里我们先来回顾一下二进制的位运算:

与运算:  &

       0 & 0 = 0

       0 & 1 = 0

       1 & 0 = 0

       1 & 1 = 1

或运算:  |

       0 & 0 = 0

       0 & 1 = 1

       1 & 0 = 1

       1 & 1 = 1

异或运算: ^

       0 ^ 0 = 0

       0 ^ 1 = 1

       1 ^ 0 = 1

       1 ^ 1 = 0

左位移运算符: << 

           将二进制码整体左移指定位数,左移后空出来的位用“0”填充

右位移运算符:>>

          >> 把操作数的二进制码右位移指定位数,左边空出来的位以原来的符号位填充。原来是负数就填充1,原来是正数就填充0

无符号右位移运算符:>>>

     >>>把操作数的二进制码右位移指定位数,左边空出来的位以0填充。无符号位右移结果总是一个正数。

我们注意看 异或运算

 我们看到如果不考虑进位,那么a+b的结果其实就是a^b的结果

  1100

  1111

————

  0011     

我们注意看 与运算 

就是只有1+1有进位,其他的都没进位。所以判断有没有进位只需要判断a&b是否等于1即可

  1100

  1111

————

  1100          向左移移一位: 11000

 

我们可以看见 第一二 步骤相加的结果 就是 1100+1111 的结果 = 11011

但是题目明确说到,不能使用 + - * % 加减乘除

借用一下大神的图:@陆艰步走

我们发现发现,a+b通过^&运算之后又再执行相加操作,所以我们首先想到的是递归

从上图,你大概可以看出,这个就是在不断重复第一,第二的步骤,那么退出条件是什么?
其实我们可以设想一个最坏的情况,那就是,这个循环到了一个情况,会在一直循环的情况,结果依然不变?
无疑,那就是,进位的结果为0的情况,所以,其实在不考虑溢位的情况下,其实最多最多就是循环32次就行,

那么咱们上代码:

递归法

// 递归法

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

非递归法

 

class Solution {
    public int add(int a, int b) {
        if(b == 0) return a;
        int c = a^b;
        int d = (a&b)<<1;
        return add(c,d);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值