128/300
- 两数相除
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
说明:
被除数和除数均为 32 位有符号整数。
除数不为 0。
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/divide-two-integers
思路:这道题看起来很简单,但其实是一道中等难度的题。
果不其然有坑——“超出时间限制”
传统思路:
n=10 | d = abs(-3) | count = 0 |
---|---|---|
7 | 3 | 1 |
4 | 3 | 2 |
1 | 3 | 3 |
10 -3 -3 -3 = 1
也就是 n - d -d- d >= 0
#class Solution:
# def divide(self, dividend: int, divisor: int) -> int:
# sig = ((dividend > 0) == (divisor > 0))
# n, d = abs(dividend), abs(divisor)
# count = 0
#
# while n >= d:
# n -= d; count += 1
#
# return min(count if sig else -count, (1 << 31) - 1)
果然,超时了。。。。【摔!
优化:不一个一个的减了,翻倍的减!
为了方便计数,引入翻倍变量m (multiple):
n=10 | d = abs(-3) | count = 0 | m = 1 |
---|---|---|---|
10 - 3 = 7 | 3 + 3 = 6 | 1 | 1 + 1 = 2 |
7 - 6 = 1 | 6 + 6 = 12 | 1 + m = 3 | 2 + 2 = 4 |
class Solution:
def divide(self, dividend: int, divisor: int) -> int:
sig = ((dividend > 0) == (divisor > 0))
n = abs(dividend)
d = div = abs(divisor)
count, m = 0, 1
while n >= div:
n -= d; count += m; m += m; d += d
if n < d: #大家翻滚得太嗨了,需要冷静reset一下
d = div; m = 1
return min(count if sig else -count, (1 << 31) - 1)
数小看不出来,来个最大的感受一下:
n= 2147483647 | d = 2 | count = 0 | m = 1 |
---|---|---|---|
2147483645 | 4 | 1 | 2 |
2147483641 | 8 | 3 | 4 |
2147483633 | 16 | 7 | 8 |
2147483617 | 32 | 15 | 16 |
2147483585 | 64 | 31 | 32 |
2147483521 | 128 | 63 | 64 |
2147483393 | 256 | 127 | 128 |
2147483137 | 512 | 255 | 256 |
2147482625 | 1024 | 511 | 512 |
2147481601 | 2048 | 1023 | 1024 |
2147479553 | 4096 | 2047 | 2048 |
2147475457 | 8192 | 4095 | 4096 |
2147467265 | 16384 | 8191 | 8192 |
2147450881 | 32768 | 16383 | 16384 |
2147418113 | 65536 | 32767 | 32768 |
2147352577 | 131072 | 65535 | 65536 |
2147221505 | 262144 | 131071 | 131072 |
2146959361 | 524288 | 262143 | 262144 |
2146435073 | 1048576 | 524287 | 524288 |
2145386497 | 2097152 | 1048575 | 1048576 |
2143289345 | 4194304 | 2097151 | 2097152 |
2139095041 | 8388608 | 4194303 | 4194304 |
2130706433 | 16777216 | 8388607 | 8388608 |
2113929217 | 33554432 | 16777215 | 16777216 |
2080374785 | 67108864 | 33554431 | 33554432 |
2013265921 | 134217728 | 67108863 | 67108864 |
1879048193 | 268435456 | 134217727 | 134217728 |
1610612737 | 536870912 | 268435455 | 268435456 |
1073741825 | 1073741824 | 536870911 | 536870912 |
1 | 2147483648 | 1073741823 | 1073741824 |