leetcode题解:两数相除

题目描述

给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

来源:力扣(LeetCode)

 题目分析

整除计算,不允许使用乘除和mod运算,因此考虑采用加减运算,比较大小来进行除法的计算。除数和被除数的符号共有四种组合(++, +-, -+, --),因此需要考虑分情况讨论或统一符号运算。

* 累加来模拟除法,如何提高效率

第一思路:递归法

采用最简单的思路,分四种情况分别逐个累加或累减操作。结果超出时间限制,单倍累加效率过低

while(cnt + cnt > dividend){

            mul += 1;

            cnt += divisor;

}

改进思路:

单倍累加过于低效,采用2的幂次方倍来逐次累加,加快搜索速度。

static long _div(long dividend, long divisor){
        if (dividend > divisor) return 0;
        long mul = 1, cnt = divisor;
        // 采用 2的幂次方来扩大步幅
        while(cnt + cnt > dividend){
            mul += mul;
            cnt += cnt;
        }
        return mul + _div(dividend - cnt, divisor);
    }

    int divide(int dividend, int divisor) {
        if (dividend == 0) return 0;
        bool sign  = (dividend > 0) ^ (divisor > 0);  // 异或操作,判断符号
        // 除数被除数都转为负数进行计算,正数最大值翻转时会出现溢出的情况
        if (dividend > 0) dividend = -dividend;
        if (divisor > 0) divisor = -divisor;
        // 此处采用递归来计算,可以考虑改为动态规划
        // 考虑到累加结果可能溢出,申请long来表示
        long res = _div(dividend, divisor);
        res = (sign)? -res : res;
        return res>INT_MAX?INT_MAX:res;
    }

猜你喜欢

转载自blog.csdn.net/li6016265/article/details/112501253
今日推荐