leetcode-29:两个数相除

考察点是:位运算。关于位运算的知识点,也可参考本博主的博文(https://blog.csdn.net/qq_36653505/article/details/81871359

题目描述
Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

就是说不用乘法,除法,求模运算来实现两个整数相除。如果溢出,返回MAX_INT。看起来很简单,我可以用除数减去被除数,直到除数小于被除数,记录减法操作的次数即可。假设是计算m/n,那么时间复杂度为O(m/n)。用Python实现后,Time Limit Exceeded。我们考虑有没有更加优化的算法呢?

分析

任何一个整数可以表示成以2的幂为底的一组基的线性组合,即num=a02^0+a12^1+a22^2+…+an2^n。基于以上这个公式以及左移一位相当于乘以2,我们先让除数左移直到大于被除数之前得到一个最大的基。然后接下来我们每次尝试减去这个基,如果可以则结果增加加2^k,然后基继续右移迭代,直到基为0为止。因为这个方法的迭代次数是按2的幂知道超过结果,所以时间复杂度为O(log(n))。
转换被除数
dividend = divisor * result + res (被除数=除数*商+余数)
其中可以被表示为:
result = 2^m + z^(m-1) + … + 1

注:考虑溢出,当被除数为-2^31,除数为-1,商为2^31,会溢出

实现(python)
def div(dividend, divisor):

    m = abs(dividend)
    n = abs(divisor)
    sign = -1 if ((dividend < 0) ^ (divisor<0)) else 1 #注意此处异或的作用
    if n == 1:
        return sign*m
    res = 0
    while m >= n:
        t = n
        p = 1
        while m >= (t << 1):
            p <<= 1
            t <<= 1
        res += p
        m -= t
    return sign*res
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值