Problem
Given two integers dividend
and divisor
, divide two integers without using multiplication, division, and mod operator.
Return the quotient after dividing dividend
by divisor
.
The integer division should truncate toward zero, which means losing its fractional part. For example, truncate(8.345) = 8
and truncate(-2.7335) = -2
.
Note:
- Assume we are dealing with an environment that could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For this problem, assume that your function returns 231 − 1 when the division result overflows.
Example 1:
1 | Input: dividend = 10, divisor = 3 |
Example 2:
1 | Input: dividend = 7, divisor = -3 |
Example 3:
1 | Input: dividend = 0, divisor = 1 |
Example 4:
1 | Input: dividend = 1, divisor = 1 |
Constraints:
-231 <= dividend, divisor <= 231 - 1
divisor != 0
Analysis
题目给出一个被除数(dividend)和除数(divisor),要求在不使用乘法、除法和模运算的前提下,完成除法运算。既然不能直接除,那就只能一个一个减了。以Example1为例,我们是怎么计算呢?用10减去3得到7,答案自增1;再用7减去3得到4,答案自增1;再用4减去3得到1,答案自增1,此时答案就是3了。
我们按照这个思路,来看看能不能把这个算法进一步进行优化,换一个被除数40,除数还是3,答案是13,所以说按照上面的步骤,我们一共有13次循环,每次答案自增1,最后才能得到答案13。我们优化的思路就是看怎么样不一步一步算到这个13,而是采用更加快速的方法。先来用3分解40,40 = 8 * 3 + 4 * 3 + 1 * 3 + 1
,可以看到3前面的系数是8、4、1,是2的次方。而实际上前面的系数就是把答案13的二进制进行了拆解。所以这里我们就可以找到规律了:
- 系数是2的n次方,先找到最大的系数$2 ^ n$,使得
2^n * 3
不大于40,此时找到了n = 3
,所以系数是8,答案加上这个系数;此时被除数变成了40 - 8 * 3 = 16
; - 然后再找到最大的系数$2^n$,使得
2^n * 3
不大于16,此时找到了n = 2
,所以系数是4,答案加上这个系数为12;此时被除数变成了16 - 4 * 3 = 4
; - 然后找到最大的系数$2^n$,使得
2^n * 3
不大于4,此时找到了n = 1
,试试所以系数是1,答案加上这个系数为13;此时被除数变成了4 - 1 * 3 = 1
,这个时候1小于除数3,计算结束。
Solution
因为找出最大系数的时候是2的次方,而题目不允许使用乘法,所以这里用位运算代替。同时要注意正负号的处理,因为正负数并不影响结果,所以可以先记录下正负号,然后都转换为正数的运算,最终返回结果的时候添加正负。
Code
1 | class Solution { |
Summary
这是一道数学类题目,本质上还是运用到了位运算。解决数学的加减乘除类型的题目要多考虑二进制和位运算,这些都是能够加快运算速度的方法。这道题目的分享到这里,感谢你的支持!