要求不使用乘法、除法和 mod 运算符,但是乘法、除法、mod都是可以使用加减进行模拟的,假设输入分别为15、3,res表示结果:
- 15 > 3: res置为1(代表结果至少为1),3 += 3(翻倍)得到6
- 15 > 6: 比翻倍之后的数还要大,res置为2(1 += 1),6 += 6得到12
- 15 > 12: res置为4,12 += 12得到24
- 15 < 24,循环终止,此时的res为4,代表15里面至少有4个3,但是还没有结束,15里面还有剩余的数,也就是(15-12 = 3)
- 用剩余部分3,和被除数3再次重回第一步
- 当除数 < 被除数的时候,直接返回0
class Solution {
public:
int divide(int dividend, int divisor) {
//if(dividend == 0 || divisor == 1) return dividend;
//if(divisor == -1) return dividend == INT_MIN ? INT_MAX : -dividend;
int sign = (dividend>0) ^ (divisor>0) ? -1 : 1; //运算结果的正负
long res = div(abs(dividend), abs(divisor));//参数传入绝对值
if(sign == 1) return res > INT_MAX ? INT_MAX : res;
return -res;
}
long div(long a, long b){//long防止溢出
if(a < b) return 0;
long cnt = 1, val = b;
while(val + val <= a){
cnt += cnt;
val += val;
}
return cnt + div(a-val, b);
}
};
如果不使用long类型,那就可以转化为负数来防止溢出:
class Solution {
public:
int divide(int dividend, int divisor) {
if(dividend == 0 || divisor == 1) return dividend;
if(divisor == -1) return dividend == INT_MIN ? INT_MAX : -dividend;
int sign = (dividend>0) ^ (divisor>0) ? -1 : 1; //运算结果的正负
int res = div(-abs(dividend), -abs(divisor));//参数传入绝对值的负值
return sign == 1 ? res : -res;
}
int div(int a, int b){
if(a > b) return 0;//因为转为负号,这儿大小关系就反过来了
int cnt = 1, val = b;
while(val-a+val >= 0){//这样写是防止溢出
cnt <<= 1;
val += val;
}
return cnt + div(a-val, b);
}
};