题目分析:
这一题是有一点难度,它的意思是让算两个数相除的商,但是不能使用乘法,除法和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)。
至此,程序的主题思想已经介绍完了,接下来要注意数据左移和求整数绝对值的边界问题。
代码说明:
1、被除数与除数异号时记录一下
if (dividend < 0 and divisor > 0) or (dividend > 0 and divisor < 0): flag = -1
2、如题目分析4
while(dividend >= divisor << n):
n += 1
res += 1 << (n - 1)
3、如题目分析5
dividend -= (divisor << (n - 1))
4、把正负号加上并判断是否越界
res = -res if flag < 0 else res
if res < -2147483648 or res > 2147483647:
return 2147483647
测试代码:
class Solution:
def divide(self, dividend, divisor):
res, flag = 0, 0
if (dividend < 0 and divisor > 0) or (dividend > 0 and divisor < 0):
flag = -1
dividend = abs(dividend)
divisor = 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
print(Solution().divide(-2147483648, 1)) #提交时请删除该行