Problem 29: Divide Two Integers
思路
这道题可以看做是二分法的应用,每次用除数来翻倍(这里用 shift),然后和被除数比较
当除数翻倍到比被除数大了以后,我们就后退一位
这道题的 corner cases 要注意
复杂度
因为每次 while loop 都是对半分,消耗
log(n)
的时间,所以总的时间复杂度是(logn)^2
public class Solution {
public int divide(int dividend, int divisor) {
if (dividend == 0) {
return 0;
}
if (divisor == 0) {
return dividend >= 0 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
}
if (dividend == Integer.MIN_VALUE && divisor == -1) {
return Integer.MAX_VALUE;
}
boolean isNegative = (dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0);
long a = Math.abs((long) dividend);
long b = Math.abs((long) divisor);
int rst = 0;
while (a >= b) {
int shift = 0;
while (a >= (b << shift)) shift++;
a -= b << (shift - 1);
rst += 1 << (shift - 1);
}
return isNegative ? -rst : rst;
}
}
易错点
corner cases
(1) 被除数为 0
(2) 除数为 0
这时候有可能是极大值,同时也有可能是极小值
极大值和极小值
Integer.MAX_VALUE; // 2^31 - 1; 2147483647 Integer.MIN_VALUE; // -2^31; -2147483648
所以当被除数是极小值,除数是 -1 的时候会溢出
数字翻倍的时候有可能溢出,转为 long 类型
long a = Math.abs((long) dividend); long b = Math.abs((long) divisor);
Last updated
Was this helpful?