LeetCode ---- 29、两数相除

题目链接

思路:

两数相除,其实就是在求被除数中包含有多少个除数。使用位运算对求解过程进行加速

代码参考自:https://leetcode-cn.com/problems/divide-two-integers/solution/javabu-shi-yong-longxing-yi-wei-xiang-jian-by-jzj1/

    public int divide(int dividend, int divisor) {
        // dividend = -2^31, divisor = -1, dividend/divisor = 2^31
        if (dividend == Integer.MIN_VALUE && divisor == -1) 
            return Integer.MAX_VALUE;

        // dividend = -2^31, divisor = -2^31, dividend/divisor = 1
        if (dividend == Integer.MIN_VALUE && divisor == Integer.MIN_VALUE) 
            return 1;

        // dividend != -2^31, divisor = -2^31, dividend/divisor = 0
        if (divisor == Integer.MIN_VALUE) 
            return 0;

        // 此处需要对被除数进行修正并记录修正值:因为下面会对被除数和除数取绝对值,
        // 为了避免被除数为整型最小值时,取绝对值会导致越界问题,
        // 所以需要对被除数进行修正,即加一个除数
        int fix = 0;
        if (dividend == Integer.MIN_VALUE) {
            // 被除数已为负数,故相加时,除数为负数则应该加除数的绝对值
            dividend += divisor > 0 ? divisor : -divisor;
            fix = divisor > 0 ? -1 : 1;   // 若除数大于0,则最终结果为负,修正值为-1
                                          // 若除数小于等,则最终结果为正,修正值为1
        }
        boolean neg = (dividend ^ divisor) < 0;     // 判断最终结果的符号
        dividend = dividend < 0 ? -dividend : dividend;  // 取绝对值
        divisor = divisor < 0 ? -divisor : divisor;   // 取绝对值
        int result = 0;    // 最终结果
        while (dividend >= divisor) {  // 当被除数比除数大时,即被除数中依旧包含有除数时
            int x = divisor;           // 记录除数
            int r = 1;                 // 因为被除数比除数大,所有起码包含有一个除数
            while (x <= (dividend >> 1)) {   // 除数小于等于被除数除以2时
                x <<= 1;                     // 除数乘以2
                r <<= 1;                     // 结果乘以2
            }
            dividend -= x;               // 减去当前除数所能接近被除数的最大值
            result += r;                 // 当前被除数中包含有r个除数
        }
        return (neg ? -result : result) + fix;    // 返回时判断正负并加上修正值
    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值