[ LeetCode 10-13] 一、两数相除(不能用 乘法 除法 和 mod运算符)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

编程熊的idea
核心思想是倍增;但是用 java 实现,建议可以用Python实现这个
在这里插入图片描述

备注:不能用乘法,除法,以及mod 用法

解法一:这个太长了,不行

		INT_MIN, INT_MAX = -2**31, 2**31 - 1
        # 7/-3 dividend表示分子  divisor表示分母
        # 考虑被除数为最小值的情况
        if dividend == INT_MIN:  # 上面为最小值
            if divisor == 1:
                return INT_MIN
            if divisor == -1:
                return INT_MAX  # 溢出
        
        # 考虑除数为最小值的情况
        if divisor == INT_MIN:
            return 1 if dividend == INT_MIN else 0
        # 考虑被除数为 0 的情况
        if dividend == 0:  # 分母为0
            return 0
        
        # 一般情况,使用二分查找 重要
        # 将所有的正数取相反数,这样就只需要考虑一种情况
        rev = False
        if dividend > 0:
            dividend = -dividend
            rev = not rev
        if divisor > 0:
            divisor = -divisor
            rev = not rev

        # 快速乘
        def quickAdd(y: int, z: int, x: int) -> bool:
            # x 和 y 是负数,z 是正数
            # 需要判断 z * y >= x 是否成立
            result, add = 0, y
            while z > 0:
                if (z & 1) == 1:
                    # 需要保证 result + add >= x
                    if result < x - add:
                        return False
                    result += add
                if z != 1:
                    # 需要保证 add + add >= x
                    if add < x - add:
                        return False
                    add += add
                # 不能使用除法
                z >>= 1
            return True
        
        left, right, ans = 1, INT_MAX, 0
        while left <= right:
            # 注意溢出,并且不能使用除法
            mid = left + ((right - left) >> 1)
            check = quickAdd(divisor, mid, dividend)
            if check:
                ans = mid
                # 注意溢出
                if mid == INT_MAX:
                    break
                left = mid + 1
            else:
                right = mid - 1

        return -ans if rev else ans

二:考虑到了位运算符,其实本质上也是递增

	INT_MIN, INT_MAX = -2**31, 2**31 - 1
    if a == INT_MIN and b == -1:  # 个例
        return INT_MAX  
    
    sign = -1 if (a > 0) ^ (b > 0) else 1  # 符号问题
    
    a, b = abs(a), abs(b)
    ans = 0
    for i in range(31, -1, -1):
        if (a >> i) - b >= 0:
            a = a - (b << i)
            ans += 1 << i
    # 位运算,没看懂
    # bug 修复:因为不能使用乘号,所以将乘号换成三目运算符
    return ans if sign == 1 else -ans

解法三:倍增

这个思路最简单

        is_neg = (dividend > 0) ^ (divisor > 0)  # 符号
        dividend, divisor = abs(dividend), abs(divisor)
        cur, mul = divisor, 1  # 分子的绝对值
        ans = 0
        while dividend >= cur:
            if cur + cur <= dividend:
                cur += cur  # cur 倍增
                mul += mul  # 倍增后 达不到倍增情况
            else:
                ans += mul  # 达不到倍增后直接加到ans
                dividend -= cur  #然后减
                cur, mul = divisor, 1

        return max(-ans, -2147483648) if is_neg else min(ans, 2147483647)
        # is_neg 这名字起得有意思哈  确定正负号

猜你喜欢

转载自blog.csdn.net/weixin_45492560/article/details/120750693