[LeetCode] Divide Two Integers

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

思路:首先想到的机试不断地减去一个数直到0为止,但是这样得复杂度为O(n),只得采用其他办法。

     任何一个整数可以表示为一组以2为底的幂的线性组合:  X=a0*2^0+a1*2^1+a2*2^2+...+an*2^n,而将一个数左移N位相当于乘以2^N,那么用被除数减去这个移位后的数,就相当于上面减去2^N个除数,这样时间复杂度是O(logn)。只要先将除数左移K位找到一个刚好小于或等于被除数的值,然后用被除数去减去这个数,同时结果加上2^k即可,再将除数向右移一位,用剩下的数去减,假如不够除数继续一位,直到k=0.

  这道题需要注意int的越界,比如

    Math.abs(Integer.MIN_VALUE)=Integer.MIN_VALUE;

    Integer.MIN_VALUE-1==Integer.MAX_VALUE;

    Integer.MAX_VALUE+1==Integer.MIN_VALUE;

  还需要注意的是,当被除数是最小值  而除数是-1的情况  这样也会越界。

    public int divide(int dividend, int divisor) {
        if(dividend==divisor) return 1;
        if(divisor==0)return Integer.MAX_VALUE;
        if(divisor==Integer.MIN_VALUE) return 0;
        boolean isNeg=(dividend^divisor)>=0?false:true;
        int res = 0;
        if(dividend==Integer.MIN_VALUE && divisor==-1)return Integer.MAX_VALUE;
        if(dividend==Integer.MIN_VALUE && divisor==1) return Integer.MIN_VALUE;
        //由于最小值的绝对值还是最小值,所以这里需要先加上除数的绝对值,
        //res=res+1,这样被除数就不会越界,同时结果也不会错误
        if(dividend==Integer.MIN_VALUE){res=1;dividend+=Math.abs(divisor);}
        dividend=Math.abs(dividend);
        divisor=Math.abs(divisor);
        if(dividend<divisor) return isNeg?-res:res;
        int maxBase=0;
        while(divisor<dividend)
        {
            if((divisor<<1)<0)
                break;
            divisor<<=1;
            maxBase++;
        }
        while(maxBase>=0)
        {
            if(dividend>=divisor)
            {
                dividend-=divisor;
                res+=1<<maxBase;
            }
            divisor>>=1;
            maxBase--;
        }
        return isNeg?-res:res;
    }
原文地址:https://www.cnblogs.com/maydow/p/4683031.html