LeetCode 刷题【29. 两数相除】

29. 两数相除

自己做

解1:逐个相减(超时)

cpp 复制代码
class Solution {
public:
    int divide(int dividend, int divisor) {
        int res = 0;                              //除数默认为0,下面的处理都是dividend>0的情况,当dividend为0时,后面会直接返回这个默认值

        if(divisor == std::numeric_limits<int>::min())                            //溢出处理
            return 0;

        if(dividend == std::numeric_limits<int>::min() && divisor == -1)          //溢出处理
            return std::numeric_limits<int>::max();

        if(dividend > 0 && divisor > 0){
            while(dividend >= divisor){
                dividend -= divisor;
                res++;
            }
        }
        else if(dividend > 0 && divisor < 0){
            while(dividend >= -divisor){
                dividend += divisor;        //相当于dividend -= -divisor,这里就是把负的部分转为正的
                res--;
            }
        }
        else if(dividend < 0 && divisor < 0){
            while(dividend <= divisor){
                dividend -= divisor;
                res++;
            }
        }
        else if(dividend < 0 && divisor > 0){
            while(dividend <= -divisor){
                dividend += divisor;
                res--;
            }
        }

        return res;

    }
};

解2:移位运算

忘了

解3:应减尽减

cpp 复制代码
class Solution {
public:
    int divide(int dividend, int divisor) {
        int res = 0;                              //除数默认为0,下面的处理都是dividend>0的情况,当dividend为0时,后面会直接返回这个默认值

        if (divisor == std::numeric_limits<int>::min() && dividend != std::numeric_limits<int>::min())  //如果dividend不为最小值,那么相除就必为0                      
            return 0;

        if (dividend == std::numeric_limits<int>::min() && divisor == -1)          //溢出处理
            return std::numeric_limits<int>::max();

        int len = 0;                                        //这里的len表示2的指数

        //分同号和异号两种情况
        if (dividend > 0 && divisor > 0 || dividend < 0 && divisor < 0) {             //同号
            if (dividend > 0 && dividend < divisor ||
                dividend < 0 && dividend > divisor)              //除数比被除数还大,相除为0
                return 0;

            //调整divisor
            while (dividend > 0 && divisor <= (dividend >> 1) ||
                   dividend < 0 && divisor >= (dividend >> 1)) {                    //divisor一开始尽可能取大
                divisor = divisor << 1;         //左移一位相当于*2
                len++;
            }

            //开始相减
            while (len >= 0) {
                if (dividend > 0 && dividend >= divisor ||
                    dividend < 0 && dividend <= divisor) {                    //如果这个对应的divisor*2**len能减(尽可能大),那就减,否则就跳过
                    dividend -= divisor;

                    res += 1 << len;
                }
                divisor = divisor >> 1;
                len--;
            }

        }

        if (dividend < 0 && divisor > 0 || dividend > 0 && divisor < 0) {       //异号
            //转为同号处理(这里divisor不为最小值)    
            divisor = -divisor;

            if (dividend > 0 && dividend < divisor ||
                dividend < 0 && dividend > divisor)              //除数比被除数还大,相除为0
                return 0;


            //调整divisor
            while (dividend > 0 && divisor <= (dividend >> 1) ||
                   dividend < 0 && divisor >= (dividend >> 1)) {                    //divisor一开始尽可能取大
                divisor = divisor << 1;         //左移一位相当于*2
                len++;
            }

            //开始相减
            while (len >= 0) {
                if (dividend > 0 && dividend >= divisor ||
                    dividend < 0 && dividend <= divisor) {                    //如果这个对应的divisor*2**len能减(尽可能大),那就减,否则就跳过
                    dividend -= divisor;

                    res += -1 << len;
                }
                divisor = divisor >> 1;
                len--;
            }

        }

        return res;

    }
};