29.两数相除

两数相除

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

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

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

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

示例 1:

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

示例 2:

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

提示:

  • $-2^{31}$ <= dividend, divisor <= $2^{31} - 1$
  • divisor != 0

解析

利用倍增思想:每次将除数翻倍(左移),快速逼近被除数,从而减少减法次数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
* @param {number} dividend
* @param {number} divisor
* @return {number}
*/
var divide = function (dividend, divisor) {
const INT_MAX = 2147483647;
const INT_MIN = -2147483648;

if (dividend === INT_MIN && divisor === -1) return INT_MAX;

const sign = (dividend > 0) ^ (divisor > 0) ? -1 : 1;
let a = Math.abs(dividend);
let b = Math.abs(divisor);
let result = 0;

while (a >= b) {
let temp = b;
let multiple = 1;
while (a >= temp + temp) {
temp += temp;
multiple += multiple;
}
a -= temp;
result += multiple;
}

return sign === 1 ? result : -result;
};

倍增法的核心思想:不断将除数翻倍来加速减法过程。时间复杂度 O(log²n)。


29.两数相除
https://leetcode.lz5z.com/29.divide-two-integers/
作者
tickli
发布于
2023年8月23日
许可协议