對除數和被除數實現除法運算,其中不使用乘法、除法和求餘操做,返回對應的商。如,
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