Divide Two Integers

1.题目

将两个整数相除,要求不使用乘法、除法和 mod 运算符。如果溢出,返回 2147483647

给定被除数 = 100 ,除数 = 9,返回 11

2.算法

这道题是关于数值运算的,比较容易想到的方法是用被除数减去除数,一直到0,如果商为n,则需要减n次,事件复杂度为n,有没有可以优化的方法呢,在网上看到有人用位运算来做这个我们就得使用位运算。我们知道任何一个整数可以表示成以2的幂为底的一组基的线性组合,即num=a_0*2^0+a_1*2^1+a_2*2^2+...+a_n*2^n。基于以上这个公式以及左移一位相当于乘以2,我们先让除数左移直到大于被除数之前得到一个最大的基。然后接下来我们每次尝试减去这个基,如果可以则结果增加加2^k,然后基继续右移迭代,直到基为0为止。因为这个方法的迭代次数是按2的幂直到超过结果,所以时间复杂度为O(logn),但是为了避免越界,要进行越界检测,越界检测如下:

1.如果除数为0,我们直接返回最大值

2.如果被除数为Integer.MIN_VALUE,除数为-1,则直接返回最大值,如果除数为Integer.MIN_VALUE,则直接返回1

3被除数为Integer.MIN_VALUE,除数不为上面两种情况,则让被除数加一个除数绝对值,在取被除数绝对值

    public int divide(int dividend, int divisor) {
        // Write your code here
    if (divisor == 0)  //当除数为0时,返回最大值
    {
        return Integer.MAX_VALUE;
    }
    boolean isNeg = (dividend^divisor) >>> 31 == 1;//检测符号位
    int res = 0;
    if (dividend == Integer.MIN_VALUE)
    {
        dividend += Math.abs(divisor);  //为避免取绝对值溢出
        if (divisor == -1)
        {
            return Integer.MAX_VALUE;
        }
        res++;
    }
    if (divisor == Integer.MIN_VALUE)
    {
        return res;
    }
    dividend = Math.abs(dividend);
    divisor = Math.abs(divisor);
    int digit = 0;
     // 为什么是小于等于,例如5 / 2,此时digit为1,如果是小于则digit为0,下面就错了
    while (divisor <= dividend>>1) 
    {
        divisor <<= 1;
        digit++;
    }
    //为什么是大于等于,如10 / 10 ,此时digit为0,下面正确,如果为大于则错
    while(digit >= 0)
    {
        if (dividend >= divisor)
        {
            res += 1 << digit;
            dividend -= divisor;
        }
        divisor >>= 1;
        digit--;
    }
    return isNeg ? -res : res;
    }

    def divide(self, dividend, divisor):
        # Write your code here
        INT_MAX = 2147483647
        if divisor == 0:
            return INT_MAX
        isNeg = dividend > 0 and divisor < 0 or dividend < 0 and divisor > 0
        a, b = abs(dividend), abs(divisor)
        res, shaft = 0, 31
        while shaft >= 0:
            if a >= b << shaft:
                a -= b << shaft
                res += 1 << shaft
            shaft -= 1
        if isNeg:
            res = -res
        if res > INT_MAX:
            return INT_MAX
        return res


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值