【lc刷题】29 两数相除_Day46(128/300)

博客围绕LeetCode上两数相除问题展开,要求不使用乘、除和mod运算符求商。给出示例及说明,指出传统思路易超时,提出优化方法,即不一个一个减,而是翻倍地减,并引入翻倍变量方便计数。

128/300

  1. 两数相除
    给定两个整数,被除数 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=10d = abs(-3)count = 0
731
432
133

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=10d = abs(-3)count = 0m = 1
10 - 3 = 73 + 3 = 611 + 1 = 2
7 - 6 = 16 + 6 = 121 + m = 32 + 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= 2147483647d = 2count = 0m = 1
2147483645412
2147483641834
21474836331678
2147483617321516
2147483585643132
21474835211286364
2147483393256127128
2147483137512255256
21474826251024511512
2147481601204810231024
2147479553409620472048
2147475457819240954096
21474672651638481918192
2147450881327681638316384
2147418113655363276732768
21473525771310726553565536
2147221505262144131071131072
2146959361524288262143262144
21464350731048576524287524288
2145386497209715210485751048576
2143289345419430420971512097152
2139095041838860841943034194304
21307064331677721683886078388608
2113929217335544321677721516777216
2080374785671088643355443133554432
20132659211342177286710886367108864
1879048193268435456134217727134217728
1610612737536870912268435455268435456
10737418251073741824536870911536870912
1214748364810737418231073741824

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值