問題描述就是簡單的兩句話:
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
題目分析
- 先考慮最普通的情況,比如
15/3 ,15=3∗5 ,答案爲5,求解的過程並不能每次都減去一個3,知道remain小於等於0,這樣的話速度會很慢,那麼,要用什麼方法加速呢。參考整數進制轉換的時候,每個整數可以用a=bc0+bc1+...+bcn 來表示。那麼,商也可以用冪來加速。這就是內循環的思路。外循環用來判斷是否要繼續下一輪找商的冪。 - 這裏還需要考慮符號問題。
- 特殊情況,需要考慮溢出,就是當dividend爲INT_MIN的時候,由於我要先把dividend先轉成正數再繼續運算,所以dividend,remain和quotient的類型都要是long long。這已經包括絕大多數的情況了。
- 還有一種特殊情況是3沒辦法處理到的。就是當dividend=INT_MIN&&divisor=-1 的時候,求出來的quotient還是
INT_MAX+1 。最後返回結果要截斷成int,會溢出,所以要在一開始加一個特殊判斷。
class Solution {
public:
int divide(int dividend, int divisor) {
if (dividend == INT_MIN && divisor == -1) {
return INT_MAX;
}
long long quotient = 0, remain = labs(dividend), base = labs(divisor);
while (remain > 0) {
int move_counter = -1;
while (remain - (base << (move_counter + 1)) >= 0) {
move_counter++;
}
if (move_counter < 0) {
break;
}
remain -= (base << move_counter);
quotient += (1 << move_counter);
if (move_counter <= 0) {
break;
}
}
int flag = (dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0) ? 1 : -1;
return flag * int(quotient);
}
};