LeetCode (31) Divide two integers (不使用 *, /, mod 求两个数相除结果)

题目描述

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

对两个数 dividend 和 divisor,在不使用乘法、除法、取余操作求它们的相除结果,最直观的做法就是反复对 dividend - divisor 进行计数,直到差小于divisor为止。但是该方法存在一个问题,当dividend很大而divisor很小(eg. 1)的时候,会出现Time Limit Exceed的问题。

这里,我们可以利用二进制的特点减少运行时间。 d 表示分子,b 表示分母

d=an2n+an12n1++a121+a020
b=bm2m+bm12m1++b121+b020


计算方法为:

  • d=db -> cnt+=1;
  • d=d2b -> cnt+=2
  • d=d2kb -> cnt+=2k
  • 直到 d2kb<0

若此时 d<b 则计算结束,否则,重复上述计算。


上面的乘法和除法因为都是与2相关的,可以用位移操作代替。

另外需要注意可能会存在overflow的问题。这里用一个宏表示溢出时的数值即可。

#define MAX_INT     2147483647 /* maximum (signed) int value */

class Solution {
public:
    int divide(int dividend, int divisor) {
        long long a = dividend;
        long long b = divisor;
        a = abs(a); b = abs(b);
        long long int res = 0;
        while (a>=b)
        {
            long long t = b;
            for (int i = 1; a >= t; i <<= 1, t <<= 1)
            {
                a -= t;
                res += i;
            }
        }

        res = ((dividend<0)^(divisor<0))? -res:res;
        if (res  > MAX_INT)
            res = MAX_INT;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值