题目:输入两个int型整数,他们进行除法计算并返回商,要求不得使用‘*’、除号‘/’以及求余符号‘%’。当发生溢出时返回最大的整数值。假设除数不为零。例如,输入15和2,输出15/2的结果,即7.
暴力方法: 针对这个题目来说,不知道算法的初步学习者最先想到的暴力方法也是可行的:采用一个循环,使得被除数一直减去除数,每减去一次商++。但是当被除数非常的大,然而除数却非常的小的时候其效率我们可想而知。
方法优化:当被除数大于除数时我们继续比较被除数是否大于被除数的二倍,如果是,继续判定被除数是否大于除数的四倍......如果被除数最多大于除数的2^k倍,那么我们直接采用被除数减去除数的2^k倍。然后将剩下的被除数重复前面的步骤,此时时间复杂度成了O(logn).
public int divide(int dividend,int divsor){
if(dividend == 0x80000000 && divisor == -1){
return Integer.MAX_VALUE;
}
int negative = 2;
if(dividend > 0){
negative--;
dividend = -dividend;//把正数变为负数
}
if(divisor > 0){
negative--;
divisor = -divisor;//把正数变为负数
}
int result = divideCore(dividend,divisor);
return negative == 1 ? -result : result;
}
private int divideCore(int dividend,int divisor){
int result = 0;//商的大小
while(dividend <= divisor)
int value = divisor;
int quotient = 1;
while(value >= 0xc0000000 && dividend <= value + value){//因为时负数所以判定用小于
quotient += quotient;
dividend -= value;
}
result += quotient;
dividend -= value;
}
return result;
}
在第一个函数中,我们把除数和被除数都从正数转变成了负数,这样可以避免溢出的一种情况,当被除数时-2^31除数为-1的时候,因为最大的正数为(2^31-1)。