LEETCODE解题笔记 —— 29.两数相除

不得使用乘除和mod运算。算出来整数,小数位丢弃

这个第一想法就是不让用乘除就用减法嘛,但是如果被除数过大,除数国小,这样效率就会非常慢。

要怎么做比较有效率呢?

假如我给一个被除数和除数 25 和 7,如何算出 3为商呢?

可以借助指数扩大的方法

将变量ans初始化为 1

每次令 除数 7 乘以 2

这时ans也乘以 2

然后用除数去和被除数对比,如果除数等于被除数,那么这时的ans就是答案,注意,如果除数*2就直接大于被除数了,那么我们就让被除数减去这时的除数,同时ans我们也记录下来

用上边的25和7举例:

就是7*2 = 14 1*2 = 2后 再循环,

14*2时发现结果28大于25了,

所以25-14 = 11,记住ans = 2

这时除数再次回到7

ans再次归1

然后再计算

7*2 = 14,啊,14>11了,所以

11-7 = 4

记住 ans = 1

除数再次回到7

ans再次归1

4 < 7了,除法无法再进行了

这时跳出所有循环结算,两次记录ans=2 ans=1 加起来为3,这时我们算出了商

 

上面的算法就是把 25拆成了 (14 + 7 + 4)/7来计算,我们算出了每一部分的商加起来就是25的商。

所以。。*2这个操作怎么算呢?累加吗?我 推荐用位运算 << 1,速度更快。

//不是我的答案
class Solution {
    public int divide(int dividend, int divisor) {
        boolean sign = (dividend > 0) ^ (divisor > 0);
        int result = 0;
        if(dividend>0) {
            dividend = -dividend;
        }
        if(divisor>0) divisor = -divisor;
        while(dividend <= divisor) {
            int temp_result = -1;
            int temp_divisor = divisor;
            while(dividend <= (temp_divisor << 1)) {
                if(temp_divisor <= (Integer.MIN_VALUE >> 1))break;
                temp_result = temp_result << 1;
                temp_divisor = temp_divisor << 1;
            }
            dividend = dividend - temp_divisor;
            result += temp_result;
        }
        if(!sign) {
            if(result <= Integer.MIN_VALUE) return Integer.MAX_VALUE;
            result = - result;
        }
        return result;
    }
}

leetcode的c++编译器不允许负数左移,很麻烦。。。

上面的代码可以看到都转换成负数计算了,因为INT_MAX可以取负号,但是INT_MIN不可以取正号。。。

涉及到边界时负数都作为负数处理会比正数好。

 

另外这个逼近商的思想和快速乘和快速幂相似,快速乘和快速幂不但速度快而且可以检测到溢出。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值