标签:注意 ++ 最小 特殊 ret etc end while 接下来
这题也是以前看过没理解,倒过来看理解的。
public int divide(int dividend, int divisor) {
int sign=1;
if(dividend>0&&divisor<0 || dividend<0&&divisor>0)
sign=-1;
int tmp=divisor;
if(divisor==0)
return 0;
if(divisor==-1){
if(dividend==Integer.MIN_VALUE)
return Integer.MAX_VALUE;
return -dividend;
}
if(divisor==1)
return dividend;
dividend=dividend>0?0-dividend:dividend;
divisor=divisor>0?0-divisor:divisor;
int i=0;
if(dividend<=divisor)
i=1;
else
return 0;
while(dividend<=divisor+divisor&&divisor+divisor<0){
i=i+i;
divisor=divisor+divisor;
}
if(sign==1)
return i+divide(dividend-divisor, tmp);
else
return 0-(i+divide(dividend-divisor, tmp));
}
另一种容易理解的拆分代码:
class Solution {
public int div(int a,int b){//a,b都为负数
int tmp=b;
if(a>b)
return 0;
int cnt=1;
while(a<=b+b&&b+b<0){//判断<0是因为防止负数相加溢出为正数
cnt+=cnt;
b+=b;
}
return cnt+div(a-b,tmp);
}
public int divide(int dividend, int divisor) {
int sign=1;//判断是否异号
if(dividend>0&&divisor<0 || dividend<0&&divisor>0)
sign=-1;
if(divisor==0)//特殊情况
return 0;
if(divisor==-1){//特殊情况
if(dividend==Integer.MIN_VALUE)//唯一一种溢出情况,负最大除-1
return Integer.MAX_VALUE;
return -dividend;
}
if(divisor==1)//特殊情况
return dividend;
dividend=dividend<0?dividend:0-dividend;//防止负最小转正最大时出错
divisor=divisor<0?divisor:0-divisor;//统一转为负数
return sign==1?div(dividend,divisor):0-div(dividend,divisor);
}
}
++ 正数最大值加1会变成负最小,负数最小减1会变成正最大。这是补码计算得出的,也叫做溢出。
++ 这题如果有记录翻倍的过程应该会更快,减少了递归次数,用空间换时间。
++ 左移一位也就是当前数翻倍(右边补0),这题的话就是将除数进行移位,因为每个位置的数都翻倍,和也会翻倍,不过要考虑溢出问题
标签:注意 ++ 最小 特殊 ret etc end while 接下来
原文地址:https://www.cnblogs.com/alike/p/13218265.html