//a不停减去b,减到a小于b,计算减了多少次,就是结果
public int divide(int a,int b){
int sign=1;
//如果a或b有一个是负数,那么就定义最后的结果为负数
if((a>0&&b<0)||(a<0&&b>0)){
sign = -1;
}
//Math.abs(-2147483648)=-2147483648
a = Math.abs(a);
b = Math.abs(b);
int res = 0;
while(a>=b){
a-=b;
res++;
}
return sign*res;
}
考虑边界问题
public int divide(int a,int b){
//环境只支持32位整数
// 32 位最大值:2^31 - 1 = 2147483647
// 32 位最小值:-2^31 = -2147483648
// -2147483648 / (-1) = 2147483648 > 2147483647 越界了
if(a==Integer.MIN_VALUE && b==-1)
return Integer.MAX_VALUE;
//如果a或b有一个是负数,那么就定义最后的结果为负数
//用异或^来判断a和b符号是否相同,都为正数或都为负数异或的结果就是false,一个为正一个为负就是true
int sign = (a>0)^(b>0)?-1:1;
if(a>0) a = -a;
if(b>0) b = -b;
int res = 0;
while(a<=b){
a -= b;
res ++;
}
return sign*res;
}
优化,考虑减去除数的倍数
// 时间复杂度:O(logn * logn),n 是最大值 2147483647 --> 10^10
public int divide(int a, int b) {
if (a == Integer.MIN_VALUE && b == -1)
return Integer.MAX_VALUE;
int sign = (a > 0) ^ (b > 0) ? -1 : 1;
if (a > 0) a = -a;
if (b > 0) b = -b;
int res = 0;
while (a <= b) {
int value = b;
int k = 1;
// 0xc0000000 是十进制 -2^30 的十六进制的表示
// 判断 value >= 0xc0000000 的原因:保证 value + value 不会溢出
// 可以这样判断的原因是:0xc0000000 是最小值 -2^31 的一半,
// 而 a 的值不可能比 -2^31 还要小,所以 value 不可能比 0xc0000000 小
// -2^31 / 2 = -2^30
while (value >= 0xc0000000 && a <= value + value) {
value += value;
// 代码优化:如果 k 已经大于最大值的一半的话,那么直接返回最小值
// 因为这个时候 k += k 的话肯定会大于等于 2147483648 ,这个超过了题目给的范围
if (k > Integer.MAX_VALUE / 2) {
return Integer.MIN_VALUE;
}
k += k;
}
a -= value;
res += k;
}
// bug 修复:因为不能使用乘号,所以将乘号换成三目运算符
return sign == 1 ? res : -res;
}
// 时间复杂度:O(1)
public int divide(int a, int b) {
if (a == Integer.MIN_VALUE && b == -1)
return Integer.MAX_VALUE;
int sign = (a > 0) ^ (b > 0) ? -1 : 1;
a = Math.abs(a);
b = Math.abs(b);
int res = 0;
for (int i = 31; i >= 0; i--) {
// 首先,右移的话,再怎么着也不会越界
// 其次,无符号右移的目的是:将 -2147483648 看成 2147483648
// 注意,这里不能是 (a >>> i) >= b 而应该是 (a >>> i) - b >= 0
// 这个也是为了避免 b = -2147483648,如果 b = -2147483648
// 那么 (a >>> i) >= b 永远为 true,但是 (a >>> i) - b >= 0 为 false
if ((a >>> i) - b >= 0) { // a >= (b << i)
a -= (b << i);
// 代码优化:这里控制 res 大于等于 INT_MAX
if (res > Integer.MAX_VALUE - (1 << i)) {
return Integer.MIN_VALUE;
}
res += (1 << i);
}
}
// bug 修复:因为不能使用乘号,所以将乘号换成三目运算符
return sign == 1 ? res : -res;
}
最初的想法://a不停减去b,减到a小于b,计算减了多少次,就是结果 public int divide(int a,int b){ int sign=1; //如果a或b有一个是负数,那么就定义最后的结果为负数 if((a>0&&b<0)||(a<0&&b>0)){ sign = -1; } a = Math.abs(a);