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; }