《C语言入门100例》(第4例) 整除(29. 两数相除leetcode)

29.两数相除

29.两数相除
题解:
在这里插入图片描述
在这里插入图片描述
这道题有点难度,但还没到让你无从下手的地步,就是需要考虑的情况太多了,有些麻烦。
当然如果你任性点,就是要用除法操作符,也是可以过的 ( ̄_, ̄ )

int divide(int dividend, int divisor){
    
    
    if((long)dividend / (long)divisor > INT_MAX || (long)dividend / (long)divisor < INT_MIN){
    
    
        return INT_MAX;
    }

    return dividend / divisor;
}

但这样就没什么挑战性了。
题目要求我们不能用乘法、除法和取模运算,那我们所能用的运算符就只有按位运算符和加法以及减法。
分析:
  如果按照上面的要求计算的话,比较容易想到的就是用加法和减法,例如计算10 / 4,就相当于计算了两次10 - 4,但是由于数据的范围较大,但是这样会超时。这是我们可以利用分而治之的算法思维,每减一次除数的大小都增加一倍。
在这里插入图片描述
这样,原本需要50次的计算,现在只需计算12次,时间复杂度为O(logC)。
  然后我们还需考虑一些特殊情况,例如当dividend = 0时,divisor = 1 时,divisor == -1时,因为题目还要求环境只能存储 32 位有符号整数,也就是说我们只能用整型,而取值范围为 [−2 ^ 31, 2 ^ 31 − 1],当divisor = -1 && dividend = −2 ^ 31时,其结果为2 ^ 31,越过了int类型的范围,如果越界,我们则直接返回dividend。
  为了方便我们计算,我们直接将dividend 和divisor先转化为负数,这样计算时,就无需再判断一些情况了,我们只需返回结果时判断该返回负数还是整数。

代码如下:

int divide(int dividend, int divisor){
    
    
    //先把特殊情况判断掉
    if(dividend == INT_MIN && divisor == -1){
    
    
        return INT_MAX;
    }
    else if(divisor == -1 && dividend != INT_MIN){
    
    
        return -dividend;
    }
    if(dividend == 0){
    
    
        return 0;
    }
    if(divisor == 1){
    
    
        return dividend;
    }
    //设置两个变量用来判断dividend和divisor的正负情况
    bool dividend_bool, divisor_bool;
    if(dividend < 0){
    
    
        dividend_bool = false;
    }
    else{
    
    
        dividend = -dividend;
        dividend_bool = true;
    }
    if(divisor > 0){
    
    
        divisor = -divisor;
        divisor_bool = true;
    }
    else{
    
    
        divisor_bool = false;
    }
    int ret = 0;
    int dividend_len = dividend;
    //当dividend_len > divisor时,说明剩下剩下的时余数部分
    while(dividend_len <= divisor){
    
    
        int divisor_len = divisor;
        int i = 1;
        //dividend_len > divisor_len则重新从divisor开始减
        while(dividend_len <= divisor_len){
    
    
            dividend_len -= divisor_len;
            ret += i;
            if((INT_MIN - divisor_len) > divisor_len)break;
            divisor_len += divisor_len;
            i <<= 1;
        }
    }
    //当两个数的同号时返回正数
    if((divisor_bool && dividend_bool) || (!dividend_bool && !divisor_bool)){
    
    
        return ret;
    }
    //异号为负
    return -ret;
}

猜你喜欢

转载自blog.csdn.net/qq_53060585/article/details/121170262
今日推荐