zoukankan      html  css  js  c++  java
  • 剑指Offer_#65_不用加减乘除做加法

    剑指Offer_#65_不用加减乘除做加法

    Contents

    题目

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

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

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

    思路分析

    又是一道脑筋急转弯的题目。不能用加减乘除运算,就只能用二进制位运算了。
    思路是通过二进制位运算模拟十进制的加法,加法分为3步:
    1. 对应位相加,得到非进位和

    • 对于二进制数字来说,异或运算可以得到非进位和。
    • 可以发现最后一位的进位我们没有计算进去,下一步我们考虑进位。
     10001(十进制的17)
    +00101(十进制的5)
    ------
     10100

    2. 计算进位结果,将需要进位的位置标记为1

    • 两个二进制数字相加,何时产生进位?只有1和1相加会产生进位。我们联想到&运算,只有1和1相&结果是1。
    • 又因为当前位进位是加到更高一位上面的,所以仅仅&运算还不够,还要将运算结果左移一位。
     10001
    &00101
    ------
     00001 << 1 = 00010

    3. 将非进位和与进位部分相加,得到最终结果

    • 可以转换为10进制数字验证,相加结果是正确的。
     10100
    +00010
    ------
     10110(十进制的22)

    解答

    class Solution {
        public int add(int a, int b) {
            int sum;//非进位和
            int carry;//进位部分
            //b==0说明进位结束,这时的a就是最终结果
            while(b != 0){
                sum = a ^ b;//异或,结果是非进位和
                carry = (a & b) << 1;//与运算后左移一位,结果是进位部分
                a = sum;
                b = carry;
            }
            return a;
        }
    }

    复杂度分析

    时间复杂度:O(1),最多只需要进行32次循环(即每一位都要进位的情况),是常数
    空间复杂度:O(1),只有常数个辅助变量

  • 相关阅读:
    入门训练 圆的面积
    入门训练 序列求和
    interface
    Horizon
    H903
    Sphinx Building Docs in horizon
    Cinder Columns
    DevStack添加Swift
    Murano py27和py34的兼容处理
    Murano Weekly Meeting 2015.12.01
  • 原文地址:https://www.cnblogs.com/Howfars/p/13398872.html
Copyright © 2011-2022 走看看