29. Divide Two Integers (两数相除)
大家好,我是一个喜欢研究算法、机械学习和生物计算的小青年,我的CSDN博客是:一骑代码走天涯
如果您喜欢我的笔记,那么请点一下关注、点赞和收藏。如果內容有錯或者有改进的空间,也可以在评论让我知道。😄
题目描述
这道题目给了两个数字,分別是被除数和除数,然后你要找到它们的商数 (余数不用理会)。这道题的难点在于不能直接用整除法或乘法找答案,严格上连这两种符号 (包括mod) 都不能使用。而且,数字限制为 32-bit 整数,所以在处理正负数时必须格外注意。
在以下的解题中,我会用两种解法。第一种是对题目不太严谨的,虽然没直接用除法找答案,但因為是用二分搜索 (binary search),所以还是用了一次来找中间数。第二种是用了bit manipulation,是参考了其他资料才明白的。相关资料我会放在参考资料上,有兴趣的可以看看。
题目原文(英语)
Given two integers
dividend
anddivisor
, divide two integers without using multiplication, division and mod operator.
Return the quotient after dividingdividend
bydivisor
.
The integerdivision
should truncate toward zero, which means losing its fractional part. For example, truncate(8.345) = 8 and truncate(-2.7335) = -2.
Example 1:
Input: dividend = 10, divisor = 3
Output: 3
Explanation: 10/3 = truncate(3.33333…) = 3.
Example 2:
Input: dividend = 7, divisor = -3
Output: -2
Explanation: 7/-3 = truncate(-2.33333…) = -2.
Note:
- Both dividend and divisor will be 32-bit signed integers.
- The divisor will never be 0.
- Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows.
解题方式 (一)
第一个方法理解比较简单。首先,我们先处理个別情況,例如 除数为 1或-1、被除数为0、整除后超过32-bit 的介限。这些情況我用 if-clause 来先搞定。然后,用neg
先存着答案是否负数 (-1为负,1为正),再用二分搜索找出答案 (返回前乘以neg
)。
class Solution:
def divide(self, dividend: int, divisor: int) -> int:
if dividend == (-2**31) and divisor == -1:
return ((2**31) - 1)
if dividend == 0 or abs(divisor) > abs(dividend):
return 0
if divisor == 1:
return dividend
if divisor == -1:
return dividend * -1
if dividend == divisor:
return 1
neg = 1
if dividend < 0:
neg *= -1
dividend = abs(dividend)
if divisor < 0:
neg *= -1
divisor = abs(divisor)
left = 1
right = dividend
while left < right:
mid = (left + right) // 2
tmp = dividend - divisor * mid
if 0 <= tmp < divisor:
print('true')
return mid * neg
elif tmp < 0:
right = mid - 1
elif tmp > divisor:
left = mid + 1
print('left')
return left * neg
解题方式 (二)
第二个方法就是用 bit manipulation。一开始也是一样,先处理好不同的个別情況;之后就可以採取bit operation。主要是我在这一塊儿也需要多加努力,所以我就不多赘述了。
class Solution:
def divide(self, dividend: int, divisor: int) -> int:
if dividend == (-2**31) and divisor == -1:
return ((2**31) - 1)
if dividend == 0 or abs(divisor) > abs(dividend):
return 0
if divisor == 1:
return dividend
if divisor == -1:
return dividend * -1
if dividend == divisor:
return 1
sign = (-1 if((dividend < 0) ^ (divisor < 0)) else 1);
dividend = abs(dividend)
divisor = abs(divisor)
quotient = 0
temp = 0
for i in range(31, -1, -1):
if (temp + (divisor << i) <= dividend):
temp += divisor << i
quotient |= 1 << i
return sign * quotient;