版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HappyRocking/article/details/83540103
给定两个整数,作为除数和被除数,计算除法结果,不能使用乘法、除法和取模运算。
备注:
两个整数都是32位有符号整数。
除数不会为0。
假设我们的环境只能处理范围为
的整数。如果除法结果溢出,则返回
。
示例:
Example 1:
Input: dividend = 10, divisor = 3
Output: 3
Example 2:
Input: dividend = 7, divisor = -3
Output: -2
思路
1、除法定义
比如要计算 a 除以 b,则可以根据除法定义,寻找到 a 中包含了多少个 b:
定义一个累加和 sum = 0,每次在 sum 上累加一个 b,同时记录当前已经累加了多少个 b,直至 sum 超过了 a 为止。
此时 b 的累加个数 -1 即为除法结果。
2、改进版
同样是需要计算出 a 中包含了多少个 b,但是每次并不是只加一个除数,而是可以一次性加上n个除数,减少时间复杂度。
当然,前提是需要知道这n个除数之和,这个可以从前面的结果直接得到:比如上一步累加完之后,统计一共累加了 m 个 b 了,那么下一次可以直接在 sum 上累加 m 个 b,因为这 m 个 b 的值已经知道了。同理,下一次累加时,就知道了 2m 个 b 的累加值了,就可以直接累加 2m 个 b。
按照这个思路,是在 sum 依次累加 个 b,每次累加的步长成指数上升,因此可以迅速使得 sum 接近 a。
但是在接近 a 时,需要反过来将步数慢慢减小,以免溢出,这时就要从 的顺序挨个试验,选择加上之后也不会使得 sum 超过 a 的累加值,最后满足 sum < a 但是 sum + b > a 即可。
python实现
def divide(dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
统计有多少个除数相加可以刚好超过被除数。
"""
if dividend == 0:
return 0
#是否是正数
is_positive = (dividend > 0 and divisor > 0) or (dividend < 0 and divisor < 0)
dividend = abs(dividend)
divisor = abs(divisor)
result = 0 # 除数的个数
sum = 0 # 除数累加结果
while(sum <= dividend):
sum += divisor
result += 1
result -= 1
if not is_positive:
result = -result
if result < -2**31 or result > 2**31 - 1:
result = 2**31 - 1
return result
def divide2(dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
改进版。
"""
if dividend == 0:
return 0
#是否是正数
is_positive = (dividend > 0 and divisor > 0) or (dividend < 0 and divisor < 0)
dividend = abs(dividend)
divisor = abs(divisor)
result = 0 # 除数的个数
sum = 0 # 除数累加结果
sum_list = [(1, divisor)] # 存放二元元组,第一位为一个正整数n,第二位为n个除数之和。
while(True):
have_pop = False
while sum_list and sum + sum_list[-1][1] > dividend: # 优先累加最大的数,如果超过被除数,则改为较小数
sum_list.pop()
have_pop = True
if not sum_list: # 所有可用加数都会溢出,则说明距离被除数的差已经不足一个除数了
break
sum += sum_list[-1][1]
result += sum_list[-1][0]
if not have_pop:
sum_list.append((sum_list[-1][0]<<1, sum_list[-1][1]<<1))
if not is_positive:
result = -result
if result < -2**31 or result > 2**31 - 1:
result = 2**31 - 1
return result
if '__main__' == __name__:
dividend = 2147483647
divisor = 1
print(divide2(dividend, divisor))