剑指 Offer II 001. 整数除法
题干

``
public class Test1 {
/**
* @param a 被除数
* @param b 除数
* @return result 结果
* <p>
* ops: ① 除数不能为0
* ② 整数范围 - 2^31 到 2^31 -1
* ③ 注意正负号 为了判断先将正负号统一为负号
* <p>
* sol: 将除数不断扩大为原来的二倍,避免重复+1复杂度过高
* 若除数二倍大于被除数时 被除数减去除数 ,继续将减完的数当作被除数 此时返回结果从 0 变为上一次乘的倍数
* 例 13/3 num=1
* 13>6 num=2
* 13>12 num=4
* 13<24 num = 8 所以result += num;
* 被除数 13-12 =1(做减法之后会判断减去之后被除数是否还大于除数
* 1 < 2 ;
* 此时被除数a = 1小于b = 2 所以直接返回 result
*
*/
public static int divide(int a, int b) {
//判断特殊情况
if (a == Integer.MIN_VALUE && b == -1) {
return Integer.MAX_VALUE;
}
if (b == 0) {
return 0;
}
//结果
int result = 0;
//增大的倍数
int num = 1;
//标志位 flag = 0 结果为负数,1为正数
int flag;
//a^b为二进制数取异或,>>>符号为无符号移位,移31位后只剩下符号位
if (((a ^ b) >>> 31) == 0) {
flag = 1;
} else {
flag = 0;
}
//将正负号统一划位负 因为在下面算法除数不断乘2,不能让其二倍的模大于2^31
if (a > 0) {
a = -a;
}
if (b > 0) {
b = -b;
}
//判断特殊情况
if (a > b) {
return 0;
}
//算法开始
if (b == -1) {
return flag == 1 ? -a : a;
} else {
//进入循环 每次a-b,若2 * 除数 <= 被除数,则 b = b * 2 判断a是否大于b,当a<b的时候退出循环
while (a <= b) {
int value = b;
while (a < value + value) {
//VALUE 不能小于Integer_Min/2
if (value < -1073741824) {
break;
}
num = num * 2;
value += value;
}
result = result + num;
a = a - value;
num = 1;
}
return flag == 1 ? result : -1 * result;
}
}

浙公网安备 33010602011771号