对除数和被除数实现除法运算,其中不使用乘法、除法和求余操做,返回对应的商。如,
Input: dividend = 10, divisor = 3
Output: 3算法
class Solution
{
public int divide(int dividend, int divisor)
{
//定义除法,被除数是最小值,除以-1时,是最大值
if(dividend == Integer.MIN_VALUE && divisor == -1)
return Integer.MAX_VALUE;
//^运算符,只有不一样时,才为true ; sign定义商是否为负数
int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;
int result = 0;
//取除数和被除数的正数形式
long x = Math.abs((long)dividend);
long y = Math.abs((long)divisor);
//统计被除数共减去多少个除数,即为商
while(x >= y)
{
x -= y;
result++;
}
return sign > 0 ? result : -result;
}
}
复制代码
class Solution
{
public int divide(int dividend, int divisor)
{
if(dividend == Integer.MIN_VALUE && divisor == -1)
return Integer.MAX_VALUE;
int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;
int result = 0;
long x = Math.abs((long)dividend);
long y = Math.abs((long)divisor);
while(x >= y)
{
int shift = 1;
//将y持续向左移位,至关于y*2^(shift);
//当y*2^(shift)< x <y*2^(shift+1)时,循环结束
while(x >= (y << shift))
{
shift++;
}
x -= y << (shift - 1);
//至关于x = y*2^(shift)+y*2^(shift-n)+.....+y*2^(0) + m;m是余数
result += 1 << (shift - 1);
}
return sign > 0 ? result : -result;
}
}
复制代码
class Solution
{
public int divide(int dividend, int divisor)
{
if(dividend == Integer.MIN_VALUE && divisor == -1)
return Integer.MAX_VALUE;
int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1;
int result = 0;
int power = 32;
//long是8字节,64位;int是4字节,32位
long x = Math.abs((long)dividend);
long y = Math.abs((long)divisor);
while(x >= y)
{
//将y*2^32增长到最大,而后逐步减少,靠近x
//y*2^power<x时结束
while((y << power) > x)
{
//每次只须要执行有限步就能找到power,不像前面中的方法,是执行O(n)步才能找到
power--;
}
x -= y << power;
result += 1 << power;
}
return sign > 0 ? result : -result;
}
}
复制代码
1.在每次循环中找到最大的k的最好的方式就是认识到k实际上是在不断缩小的。所以,咱们不须要在每次子循环的时候都检验一下21,22,23......是否小于或者等于x,咱们能够在找到最大的k后,直接在后面的每次循环中检验x和2k-1,2k-2,2k-3....的关系。
2. 咱们能够继续以前的例子。商为(100)2后,咱们继续计算(11)2。由于y*2k<=x的最大k是0,因此咱们把20=(1)2加到商里,所以商就变成了(101)2。而后咱们继续算法,所以(1)2<y,因此算法结束。最后,咱们能够获得,x= (1011)2,y=(10)2相除,商为(101)2,余数为(1)2。bash