编程熊的idea
核心思想是倍增;但是用 java 实现,建议可以用Python实现这个
备注:不能用乘法,除法,以及mod 用法
解法一:这个太长了,不行
INT_MIN, INT_MAX = -2**31, 2**31 - 1
# 7/-3 dividend表示分子 divisor表示分母
# 考虑被除数为最小值的情况
if dividend == INT_MIN: # 上面为最小值
if divisor == 1:
return INT_MIN
if divisor == -1:
return INT_MAX # 溢出
# 考虑除数为最小值的情况
if divisor == INT_MIN:
return 1 if dividend == INT_MIN else 0
# 考虑被除数为 0 的情况
if dividend == 0: # 分母为0
return 0
# 一般情况,使用二分查找 重要
# 将所有的正数取相反数,这样就只需要考虑一种情况
rev = False
if dividend > 0:
dividend = -dividend
rev = not rev
if divisor > 0:
divisor = -divisor
rev = not rev
# 快速乘
def quickAdd(y: int, z: int, x: int) -> bool:
# x 和 y 是负数,z 是正数
# 需要判断 z * y >= x 是否成立
result, add = 0, y
while z > 0:
if (z & 1) == 1:
# 需要保证 result + add >= x
if result < x - add:
return False
result += add
if z != 1:
# 需要保证 add + add >= x
if add < x - add:
return False
add += add
# 不能使用除法
z >>= 1
return True
left, right, ans = 1, INT_MAX, 0
while left <= right:
# 注意溢出,并且不能使用除法
mid = left + ((right - left) >> 1)
check = quickAdd(divisor, mid, dividend)
if check:
ans = mid
# 注意溢出
if mid == INT_MAX:
break
left = mid + 1
else:
right = mid - 1
return -ans if rev else ans
二:考虑到了位运算符,其实本质上也是递增
INT_MIN, INT_MAX = -2**31, 2**31 - 1
if a == INT_MIN and b == -1: # 个例
return INT_MAX
sign = -1 if (a > 0) ^ (b > 0) else 1 # 符号问题
a, b = abs(a), abs(b)
ans = 0
for i in range(31, -1, -1):
if (a >> i) - b >= 0:
a = a - (b << i)
ans += 1 << i
# 位运算,没看懂
# bug 修复:因为不能使用乘号,所以将乘号换成三目运算符
return ans if sign == 1 else -ans
解法三:倍增
这个思路最简单
is_neg = (dividend > 0) ^ (divisor > 0) # 符号
dividend, divisor = abs(dividend), abs(divisor)
cur, mul = divisor, 1 # 分子的绝对值
ans = 0
while dividend >= cur:
if cur + cur <= dividend:
cur += cur # cur 倍增
mul += mul # 倍增后 达不到倍增情况
else:
ans += mul # 达不到倍增后直接加到ans
dividend -= cur #然后减
cur, mul = divisor, 1
return max(-ans, -2147483648) if is_neg else min(ans, 2147483647)
# is_neg 这名字起得有意思哈 确定正负号