LeetCode 0029 -- 两数相除

两数相除

题目描述

给定两个整数,被除数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。

解题思路

个人AC

无。

最优解

参考:LeetCode 题解

使用位移法:左移1相当于乘以2,右移1相当于除以2。

解题思路:

若计算100 / 3,且100 = 3 * 33 + 1,其中33 = 32 + 1 = 2 ^ 5 + 2 ^ 0。我们可以用100不断减去3的倍数,直到值小于3为止。

实质:当dividenddivisor都为正数时,用dividend不断减去divisor的倍数,直到dividend < divisor为止。否则,若当dividenddivisor都为负数时,用dividend不断加上divisor的倍数,直到dividend > divisor为止。

class Solution {
    public int divide(int dividend, int divisor) {
        // 根据被除数和除数得出最后结果的符号:负负得正
        boolean positive = (dividend > 0) ^ (divisor > 0);
        // 改用负数计算
        dividend = dividend > 0 ? -dividend : dividend;
        divisor = divisor > 0 ? -divisor : divisor;
        
        int result = 0;
        while (dividend <= divisor) { // dividend和divisor都为负数
            int tmp = divisor; // 找到当前不小于dividend的divisor的最大倍数
            int tmp_result = -1; // divisor的倍数
            while (dividend <= (tmp << 1)) {
                // 如果移位超出负数边界
                if (tmp <= (Integer.MIN_VALUE >> 1)) break;
                tmp <<= 1; // divisor * 2
                tmp_result <<= 1;
            }
            dividend -= tmp; // dividend加上当前不小于dividend的divisor的最大倍数
            result += tmp_result; // divisor的总倍数,(-2)^5 + (-2)^0 = -33
        }
        
        if (!positive) {
            if (result <= Integer.MIN_VALUE) return Integer.MAX_VALUE;
            result = -result;
        }
        return result;
    }
}

时间复杂度: O ( ) O() O()

空间复杂度: O ( 1 ) O(1) O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值