Leetcode 第29题:Divide Two Integers--两数相除(C++、Java、Python)

题目地址:Divide Two Integers

参考网址:leetcode discuss


 

题目简介:

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

Example 1:

Input: dividend = 10, divisor = 3
Output: 3

Example 2:

Input: dividend = 7, divisor = -3
Output: -2

说明:被除数和除数均为32位有符号整数,并且除数不为0。假设环境只能存储32位有符号整数,数值范围是[\left [-2 \hat{ } 31, 2 \hat{ } 31 - 1 \right ]],如果有溢出,则返回2\hat{ } 31 - 1


题目解析:数值位移

很简单的想法自然是将除法看作减法,每次减去被除数,商加1然后进行循环。但是,这种做法会导致超时。根据官网提供代码,得出了一个思路,那便是“得寸进尺”。该方法的思想还是减法,但是对能够进行减法的被减数进行处理。于是,本题可以化简为以下几个方面:

  1. 首先判断商值是否会溢出,考虑到溢出的情况只有被除数为-2147483648和除数为-1时,加一个判断。
  2. 还有几个简单的情况,例如除数为1和-1,或者被除数为0可以直接返回结果。
  3. 对被除数和除数取整,方便计算。在被除数大于除数的前提下,当被除数可以被操作时,每次减去除数后,将除数增大一倍,记住此时除数对应的数值,商加上上述数值。到除数增大的倍数足够时,便设置除数为最初的除数的取整,从头开始,直到被除数小于除数。
  4. 判断是否异号,因为32位的负数的最右边为1,正数为0。可以将两数进行异或运算,取第32位的值,如果是1则代表异号,相反为同号。

C++代码:

class Solution {
public:
    int divide(int dividend, int divisor) {
        //前面四种特殊的情况
        if (dividend == INT_MIN && divisor == -1)
            return INT_MAX;
        else if (divisor == 1)
            return dividend;
        else if(divisor == -1)
            return -dividend;
        else if (dividend == 0)
            return 0;
        
        //这里使用的是fabs,可以对INT_MIN进行取整
        long long divid = fabs(dividend);
        long long divis = fabs(divisor);
        
        int quotient = 0;//商
        while(divid >= divis)
        {
            long long temp = divis;

            //只要还能减,便得寸进尺
            for(int i = 0;temp <= divid; i++)
            {
                divid -= temp;
                quotient += 1 << i;
                temp = temp << 1;
            }
        }
        //利用32位判断是否为负数 
        return ((dividend^divisor)>>31) ? (int)(-quotient) : (int)(quotient);
    }
};

Python版:

class Solution:
    def divide(self, dividend: int, divisor: int) -> int:
        if dividend == -1 << 31 and divisor == -1:
            return (1 << 31) - 1
        elif divisor == 1:
            return dividend
        elif divisor == -1:
            return -dividend
        elif dividend == 0:
            return 0
        
        divid = abs(dividend)
        divis = abs(divisor)
        quotient = 0
        
        while divid >= divis:
            temp = divis
            i = 0
            while (temp <= divid):
                divid -= temp
                quotient += 1 << i
                temp = temp << 1
                i += 1
                
        if((dividend^divisor)>>31):
            return -quotient
        else:
            return quotient

Java代码:

class Solution {
    public int divide(int dividend, int divisor) {
        if (dividend == (-1 << 31) && divisor == -1)
            return (1 << 31) - 1;
        else if (divisor == 1)
            return dividend;
        else if(divisor == -1)
            return -dividend;
        else if (dividend == 0)
            return 0;
        else if (dividend == divisor)
            return 1;
        
        long divis = Math.abs(divisor);
        long divid;
        if (dividend == -2147483648)
        {
            divid = 2147483648L;
        }
        else
            divid = Math.abs(dividend);
        int quotient = 0;
          
        while(divid >= divis)
        {
            long temp = divis;
            for(int i = 0;temp <= divid; i++)
            {
                divid -= temp;
                quotient += 1 << i;
                temp = temp << 1;
            }
        }
        
        return ((dividend^divisor)>>31 == -1) ? (int)(-quotient) : (int)(quotient);
    }
}

 

你可能感兴趣的:(leetcode)