Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
两个数做除法,但是不能用乘法,除法和模操作符。如果溢出,返回INT_MIN 或INT_MAX.
思路:就是用被除数减去除数,减尽为止。每次把除数乘2(左移一位)直到大于被除数,然后减去移位后的除数(tmp值),再做下一轮循环,所以被除数每次至少折半。
复杂度:外层循环m每次至少折半,复杂度O(log(N)), 内层循环最多log(N)次迭代,所以复杂度O(log(N)^2)
Attention:
1. 复合操作符
“+= -= *= /= %=” (常见) “<<= >>= &= ^= |=” (不太常见) a op b <=> a = a op b
2. 位操作符
“~ 位求反; & 位于; ^ 位异或; | 位或; << 左移; >> 右移”
3. 溢出
int的绝对值,int里面有一个特殊的数字:-2147483648,它的绝对值或者相反数 2147483648是超出int的范围的,对于这一情况需要特殊处理。
4. 返回值
需要判定被除数和除数是否异号,如果异号返回ans的相反数,如果同号返回ans.
AC Code:
class Solution { public: typedef long long ll; int divide(int dividend, int divisor) { //两个数做除法,但是不能用乘法,除法和模操作符。 //思路就是用被除数减去除数,减尽为止 ll m = abs((ll)dividend); ll n = abs((ll)divisor); ll ans = 0; if(dividend == INT_MIN && divisor == (-1)) return INT_MAX; else if(dividend == INT_MIN && divisor == (1)) return INT_MIN; while(m >= n) { ll a = n; ll r = 1; while((a << 1) < m) { a <<= 1; r <<= 1; } ans += r; m -= a; } return ((dividend > 0) ^ (divisor > 0)) ? -ans : ans; } };