leetcode 29.两数相除

题目链接:leetcode 29

1.题目

给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。

整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。

返回被除数 dividend 除以除数 divisor 得到的 商 。

注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [−231, 231 − 1] 。本题中,如果商 严格大于 231 − 1 ,则返回 231 − 1 ;如果商 严格小于 -231 ,则返回 -231 。

2.示例

1)示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = 3.33333… ,向零截断后得到 3 。

2)示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = -2.33333… ,向零截断后得到 -2 。

3)提示:
-231 <= dividend, divisor <= 231 - 1
divisor != 0

3.分析

1)首先考虑特殊情况,也就是最后结果的符号问题可以使用(divisor<0)^(dividend<0)来存储,然后把divisor和dividend转化为绝对值,将问题转化为两个正数相除,并且考虑到32位int的问题,需要对正数结果进行特判

2)快速乘
考虑我们平时的乘法运算

88 * 99 = 88 * 9 * 10^0 + 88 * 9 * 10^1
        = 792 + 7920
        = 8712
88 * 0110 0011(2) = 88 * 0 * 2^7 
                  + 88 * 1 * 2^6 
                  + 88 * 1 * 2^5 
                  + 88 * 0 * 2^4 
                  + 88 * 0 * 2^3 
                  + 88 * 0 * 2^2 
                  + 88 * 1 * 2^1
                  + 88 * 1 * 2^0

两个乘数相乘可以转化为二进制位运算,x*y,x不断<<1,y>>1,当y&1==1时,最后结果+x

3)二分
可以将两数相除转化为两数相乘,也就是要找到最大的x使得x*divisor<=dividend

4.代码

def ksc(x,y):
    res=0
    while y:
        if y&1:
            res=res+x
        x=x<<1
        y>>=1
    return res
class Solution(object):
    
    def divide(self, dividend, divisor):
        # a=1
        # for i in range(31):
        #     a*=2
        # return a

        op=(dividend<0)^(divisor<0)
        divisor=abs(divisor)
        dividend=abs(dividend)

        left,right=0,dividend
        while left+1<right:
            mid=(left+right)/2
            ans=ksc(mid,divisor)
            if ans>dividend:
                right=mid
            else:
                left=mid
        ans=ksc(right,divisor)
        if ans>dividend:
            if op==1:
                return -left
            else:
                if left>=2147483648:
                    return 2147483647
                return left
        if op==1:
            return -right
        else:
            if right>=2147483648:
                return 2147483647
            return right

你可能感兴趣的:(leetcode,leetcode,算法)