classSolution { publicintdivide(int dividend, int divisor) { // 解题思路:使用二分搜索寻找最接近的商 // 定义 z = x / y, 我们需要计算出 z, 为了防止溢出,必须对一些特例进行处理 intx= dividend, y = divisor;
// 对于 32 位有符号整数,下界为 -2^31, 上界为 2^31 - 1, 即对于边界时的数字部分,负数要比正数大 1 // 在符号不相同时,将正数转换为负数不会发生越界,而负数转换为正数可能发生越界,所以我们统一把 x 和 y 转换为负数进行计算以便求 z // 在转换之前我们需要处理 -2^31 这个特殊的数 if (x == Integer.MIN_VALUE) { if (y == -1) { // 当被除数为 -2^31, 除数为 -1 时 z = 2^31, 此时无法用正数进行表示,会触发越界 return Integer.MAX_VALUE; } if (y == 1) { // 当被除数为 -2^31, 除数为 1 时 z = -2^31, 此时提前返回,以便于后续在 [1, Integer.MAX_VALUE] 中搜索 z return Integer.MIN_VALUE; } }
if (y == Integer.MIN_VALUE) { // 除了自身没有其他数能除尽 -2^31 return x == Integer.MIN_VALUE ? 1 : 0; } intsign=1;
if (x > 0) { x = -x; sign = -sign; } if (y > 0) { y = -y; sign = -sign; }
// 现在 x 与 y 均为负数,z * y >= x > (z + 1) * y, 我们寻找最小的 z * y, 即寻找最大的 z, 此时使用二分搜索一步步缩小范围 intleft=1, right = Integer.MAX_VALUE; // [left, right] intres=0; while (left <= right) { intmid= (left + right) >>> 1; if (productGreaterOrEqualTo(mid, y, x)) { res = mid; // 记录下最后一个满足条件的 z // 注意处理 mid 的越界 if (mid == Integer.MAX_VALUE) { break; } left = mid + 1; } else { right = mid - 1; } }
return sign > 0 ? res : -res; }
privatebooleanproductGreaterOrEqualTo(int z, int y, int x) { // 判断 z * y >= x 是否满足,其中 z 大于 0, x 和 y 都小于 0 // 因为不能使用乘法,所以使用加法计算
intres=0; while (z > 0) { if ((z & 1) == 1) { // z 为奇数,直接累加 y 至 res 上,累加前判断是否越界 if (res < x - y) { returnfalse; } res += y; } if (z > 1) { if (y < x - y) { returnfalse; } y <<= 1; } z >>= 1; }