LeetCode算法题--------两数相除

问题:

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

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

示例 1:

输入: dividend = 10, divisor = 3
输出: 3
示例 2:

输入: dividend = 7, divisor = -3
输出: -2
说明:

被除数和除数均为 32 位有符号整数。
除数不为 0。
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。

解:

class Solution {
public:
    int divide(int dividend, int divisor) {

        //特殊情况,即会溢出的情况
        if (dividend == INT_MIN&&divisor == -1) {
            return INT_MAX;
        }

        return recursion(dividend, divisor);

    }

    //本题的思路是把a/b拆分成(c+d)/b,即c/b+d/b,实现起来很简单
    //难就难在你得考虑一些边缘情况,比如算法中的某些中间量可能会溢出
    int recursion(int dividend, int divisor) {
        int temp;
        int i;
        int quotient;
        int sign;
        const int overflow = 1 << 30;//溢出判断数
        bool flag;//溢出标志位,对溢出进行预测

        if (-abs(dividend)>-abs(divisor)) {
            return 0;
        }

        //对商的正负性进行判断
        sign = (dividend >= 0) ^ (divisor >= 0) ? -1 : 1;

        i = 0;

        temp = divisor;

        //待侦察数是temp,即测试temp是否即将溢出
        //temp和divisor同号
        //若待侦察数为负数,则(overflow&temp)=0代表即将溢出
        //若为正数,则(overflow&temp)!=0代表即将溢出
        //flag==1表示即将溢出
        flag = (divisor < 0) ^ (bool)(overflow&temp);

        //直到temp取到小于dividend的最大数
        while ((!flag)&&(-abs(dividend) < -abs(temp << 1))) {

            temp = temp << 1;
            i++;
            flag = (divisor < 0) ^ (bool)(overflow&temp);

        };

        //temp必须与dividend同号,由于原来temp的符号取决于divisor,故这里用sign做判断
        if (sign == -1)temp = -temp;

        //quotient是c/b的商
        quotient = (sign>0 ? 1 : -1) << i;


        //递归计算d/b的商并将两个商相加
        return quotient + recursion(dividend - temp, divisor);

    }
};

你可能感兴趣的:(LeetCode算法实战)