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.
Example 1:
Input: dividend = 10, divisor = 3 Output: 3
Example 2:
Input: dividend = 7, divisor = -3 Output: -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.
LeetCode:链接
这一题是有一点难度,它的意思是让算两个数相除的商,但是不能使用乘法,除法和mod运算。一开始想到循环相减,但是数据范围在[−231, 231 − 1]。减法会TLE,参考了这篇博客发现可以用移位操作代替乘法。主要方法如下:
被除数/除数=商 (忽略余数)=> 被除数=除数*商。
商(任意整数)可以表示为:a_0 * 20+a_1 * 21+…+a_i * 2i+…+a_n * 2n.
在python中左移操作<<相当于对一个数乘以2,右移操作相当于除以2.
我们让除数左移直到大于被除数前的的一个数,例如计算28/3,我们进行三次左移操作,使3 * 2 * 2 * 2=3 * 8=24<28(注意四次左移操作得到3 * 24=48>28).记录下2 * 2 * 2=23=8.
我们让28减去24得到4,然后像第四步一样计算4/3,则3 * 20=3<4.记录下20=1.
由于4-3=1小于除数3,停止计算,并将每轮得到的值相加,在本例中8+1=9,记得到商(即28/3=9)。
至此,程序的主题思想已经介绍完了,接下来要注意数据左移和求整数绝对值的边界问题。
class Solution(object):
def divide(self, dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
"""
flag, res = 1, 0
if (dividend > 0 and divisor < 0) or (dividend < 0 and divisor > 0):
flag = -1
dividend, divisor = abs(dividend), abs(divisor)
while dividend >= divisor:
n = 0
while dividend >= divisor << n:
n += 1
res += 1 << (n-1)
dividend -= divisor << (n-1)
res = -res if flag < 0 else res
if res < -2147483648 or res > 2147483647:
return 2147483647
return res