思路:
1.负数转化为正数符合我们的习惯,但是有效区间为[−2^31, 2^31 − 1],显然−2^31,转化为正数会溢出。那么只能全部转化为负数来做了。
2.直接减肯定会超时,不然这题没意义了。其实这一题就是看dividend 最多可以分解为多少个divisor 。
我们先假设dividend >0且divisor >0。
因为无法用乘法,我们可以用位运算,每次左移n位,则相当于divisor *(2^n)了。我们试探性的累加n,直到不能加为止。
int n = 0;//这一次左移几位,初始为0
int res = 0;//结果
while(dividend >= (divisor<<n)){
// 减去了2^n个
dividend -= divisor<<n;
// 1<<n == 2^n
res += 1<<n;
n++;
}
当然,这样累加中间肯定会漏掉许多,所以当循环退出后,我们应该继续做同样的事情,写个递归就ok。
下面是完整代码:
说明: divisor<<n < 0 这个是因为我觉得负数溢出时,会变正数,未仔细想,反正就是个环嘛。
class Solution {
public int divide(int dividend, int divisor) {
int reverse = 0;
if(dividend > 0) {
dividend = 0-dividend;
reverse++;
}
if(divisor > 0) {
divisor = 0-divisor;
reverse++;
}
int res = dfs(dividend,divisor);
// 处理结果
if(reverse == 1) {
return res;
}else {
// 反转可能会溢出
if(res == Integer.MIN_VALUE) {
return Integer.MAX_VALUE;
}
return 0-res;
}
}
private int dfs(int dividend, int divisor) {
if(dividend > divisor){
return 0;
}
int res = 0;
int n = 0;
while(divisor<<n < 0 && dividend <= divisor<<n){
// 减去了2^n个
dividend -= divisor<<n;
// 2^n
res -= 1<<n;
// 退出条件
if(dividend == 0) {
return res;
}
n++;
}
return res + dfs(dividend,divisor);
}
}