一、 題目
不使用乘法、除法、求餘運算實現除法運算,除數和被除數、結果都是用int型。
如果溢出就返回MAX_INT。
二、 分析
看到題目後我立馬想到了計算機組成原理中的一位除法和二位除法,不過想想在這裏實現起來又是太麻煩了。
那就先試試暴力法吧,被除數 - 除數 = ???一直減減減直到小於等於0,想想自己都覺得超時。。。如下,果然超時
class Solution {
public:
int divide(int dividend, int divisor) {
int count = 0;
int flag = 1;
if(dividend < 0)
flag = -flag;
if(divisor < 0)
flag = -flag;
dividend = abs(dividend);
divisor = abs(divisor);
while(dividend > 0){
dividend -= divisor;
count ++;
}
return flag * count;
}
};
那怎麼辦呢?使用減的思路是對的,但是就看怎樣加快步驟了,只有移位了,我們每次如果夠減的話就增大移位,直到不夠減,此時說明該數夠大了,然後當被除數減過這個數了,雖然不能減去除數的大的倍數,但是小的還是可以的,此時我們將n = 0, 再次移位到能減的最大值,當然我們直到這個數一定小於上一個數,依次類推移位依次減少,直到最後被除數小於除數結束。PS:網上很多說將int改爲long就不會出現-2147483648的問題,但是我還是遇到了,不知道爲什麼,就算是他們說的可以AC的代碼還是出現了這個問題,我最後特殊處理下這個問題才通過。AC代碼如下:
class Solution {
public:
int divide(int dividend, int divisor) {
if(dividend == 0 || divisor == 1)
return dividend;
int count = 0;
int flag = 1;
if(dividend < 0)
flag = -flag;
if(divisor < 0)
flag = -flag;
long pdividend = abs((long)dividend);
long pdivisor = abs((long)divisor);
while(pdividend >= pdivisor){
int n = 0;
while(pdividend >= pdivisor<<(n + 1))
n++;
pdividend -= pdivisor<<n;
count += 1<<n;
}
count = flag * count;
if(count <= -2147483648 || count > 2147483647)
return 2147483647;
return count;
}
};