1

题目详情

Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.

题目要求我们在不借助乘法运算、除法运算和模运算的基础上,求出输入的两个整数相除的结果。如果溢出,那么返回MAX_INT。其中第一个参数是被除数,第二个参数是除数。

想法

  • 这道题既然不能借助乘、除、模三种运算,我们只能运用加减法求结果。
  • 很容易想到,我们每次用被除数减去除数,进行减法的次数就是最终结果。但是这种方法在遇到被除数很大,而除数很小的情况时,运算时间太长,会导致超时。
  • 这道题的采取了一种类似‘二分查找’的思想。对于每一次运算,我们要尽可能找出除数的倍数n,使得n倍的除数尽可能接近被除数的大小。
  • 如何找到这个倍数n呢?我们每次将除数翻倍,倍数为1,2,4,8,16...直到除数的n倍比被除数大。
  • 这个时候我们就用被除数减去n倍的除数,继续这样计算下去。
  • 最后我们得到的所有倍数的和,就是最后的答案。
  • 除了这些,这道题还要注意一些边界情况的判断,例如除数或被除数为0,值溢出等。

解法

    public int divide(int dividend, int divisor) {
        boolean isPositive = true;
        
        if((dividend < 0 && divisor >0) || (dividend > 0 && divisor < 0)){
            isPositive = false;
        }
        
        long ldividend = Math.abs((long)dividend);
        long ldivisor = Math.abs((long)divisor);
        
        if(ldivisor == 0)return Integer.MAX_VALUE;
        if(ldividend == 0)return 0;
        
        long lans = ldivide(ldividend, ldivisor);
        
        int ans;
        if (lans > Integer.MAX_VALUE){ 
            ans = (isPositive)? Integer.MAX_VALUE : Integer.MIN_VALUE;
        } else {
            ans = (isPositive) ? (int)lans : -(int)lans;
        }
        return ans;
    }
    private long ldivide(long ldividend, long ldivisor) {
        if (ldividend < ldivisor) return 0;
        
        long sum = ldivisor;
        long multiple = 1;
        while ((sum+sum) <= ldividend) {
            sum += sum;
            multiple += multiple;
        }
        return multiple + ldivide(ldividend - sum, ldivisor);
    }

soleil阿璐
350 声望45 粉丝

stay real ~