目录

0029:两数相除(★)

力扣第 29 题

题目

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

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

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

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

示例 1:

输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = 3.33333.. ,向零截断后得到 3 。

示例 2:

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

提示:

  • -231 <= dividend, divisor <= 231 - 1
  • divisor != 0

分析

  • 最简单的想法
    • 先把两个数都变成正的
    • 然后被除数不断的减去除数直到小于除数为止
    • 最后再加上正负号
    • 溢出的唯一可能是 −2^31 除以 -1 等于 2^31-
  • 加法太慢会超时, 考虑将除数不断自加,相当于乘 2,就可以快速的逼近了
    • 以求 divide(100, 3) 为例
    • 将 3 不断自加直到 96 (3 的 32 倍),即转化为求 32+divide(4, 3)

解答

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Solution:
    def divide(self, dividend: int, divisor: int) -> int:
        flag = dividend^divisor>=0
        a,b = abs(dividend),abs(divisor)
        A,w = [],1
        while b<=a:
            A.append((b,w))
            b,w = b+b,w+w
        res = 0
        for b,w in A[::-1]:
            if a >= b:
                a -= b
                res += w
        return min(res if flag else -res, 2147483647)

35 ms