1.题目
2.解法
class Solution {
public int divide(int dividend, int divisor) {
// 判断是否同号,同号的最后的结果为正
boolean sign = (dividend > 0) ^ (divisor > 0);
// 将所有的正号都换成负号,因为MIN_VALUE不能转正号
if (dividend > 0) dividend = -dividend;
if (divisor > 0) divisor = -divisor;
// 当除数大于等于被除数时进入循环, 因为是负数
//除数等于, 有可能被除数除数相等
// 被除数大于除数的话(负数),转为正数,商为0
int result = 0; // 记录次数
while (dividend <= divisor) {
int tmp_result = -1; // 如果被除数除数相等就为-1
int tmp_divisor = divisor;
// 这里先<<1,是为了预防, 在dividend不大于之前退出
// 不能超,一旦超了,就不能计算出准确的次数了
while (dividend <= (tmp_divisor << 1)) {
// 效果小于于前一个数,乘以2后,也是小于,会溢出
// 如果等于的话,tmp_result已经默认为-1
if (tmp_divisor <= (Integer.MIN_VALUE >> 1)) break;
tmp_divisor = tmp_divisor << 1;
tmp_result = tmp_result << 1;
}
dividend -= tmp_divisor;
result += tmp_result;
}
if (!sign) {
// 除数结果溢出,因为要转换成正数,所以等于MIN也算返回最大值
if (result <= Integer.MIN_VALUE) return Integer.MAX_VALUE;
result = -result;
}
return result;
}
}
循环条件判断一次是一次,所以时间复杂度为商O(result),空间复杂度为O(1)
3.思考
@1:位运算符是用2进制位运算的,异或相同为0,不同为1,参考链接描述
整体就是利用移位,加速减的过程