难度:中等
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2
思路:最简单的就是减法思路,例如10-3-3...一直到小于三时记录次数即可。但是本题有几个难点,第一是正负号问题,第二是时间复杂度问题,例如1000000000除2或者除1,那时间复杂度就很可怕了。
解决方案:首先对1进行判断,假设除数是1,直接返回即可;时间复杂度这里提高一个思路就是,扩大除数,例如我计算3000000和2,我将2扩大1000倍,3000000-2000....记录一个次数l1,余数再对2做减法,记录次数为l2,则结果为l1*1000+l2,这也可以明显缩减时间复杂度,真是可以弄一个梯度,例如*10000记录l1,*1000记录l2,*100记录l3,这种会更高效。
代码1(仅扩大1000倍,时间复杂度打败6%+):
class Solution(object):
def divide(self, dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
"""
flag=0;
x=1;
#x记录正负
if dividend<0:
x=x*-1;
dividend=-dividend
if divisor<0:
x=x*-1;
divisor=-divisor
l=0
#不加这个会超时,扩大除数
while(dividend>=divisor*1000):
dividend=dividend-(divisor*1000)
l=l+1
#判断除数是否为1
if divisor==1:
flag=dividend
else:
#扩大后的余数再记录次数
while(dividend>=divisor):
dividend=dividend-divisor
flag=flag+1
flag=x*(flag+l*1000)
if flag >=2147483648 or flag<=-2147483649:
flag=2147483647
return flag
代码2(梯度扩大,时间复杂度打败66%+):
class Solution(object):
def divide(self, dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
"""
flag=0;
x=1;
#x记录正负
if dividend<0:
x=x*-1;
dividend=-dividend
if divisor<0:
x=x*-1;
divisor=-divisor
l0,l1,l2,l3,l4,l5,l6=0,0,0,0,0,0,0
#梯度扩大
# while(dividend>=divisor*10000000):
# dividend=dividend-(divisor*10000000)
# l0=l0+1
while(dividend>=divisor*1000000):
dividend=dividend-(divisor*1000000)
l1=l1+1
while(dividend>=divisor*100000):
dividend=dividend-(divisor*100000)
l2=l2+1
while(dividend>=divisor*10000):
dividend=dividend-(divisor*10000)
l3=l3+1
while(dividend>=divisor*1000):
dividend=dividend-(divisor*1000)
l4=l4+1
while(dividend>=divisor*100):
dividend=dividend-(divisor*100)
l5=l5+1
while(dividend>=divisor*10):
dividend=dividend-(divisor*10)
l6=l6+1
#判断除数是否为1
if divisor==1:
flag=dividend
else:
#扩大后的余数再记录次数
while(dividend>=divisor):
dividend=dividend-divisor
flag=flag+1
flag=x*(flag+l6*10+l5*100+l4*1000+l3*10000+l2*100000+l1*1000000+l0*10000000)
if flag >=2147483648 or flag<=-2147483649:
flag=2147483647
return flag