整数除法 JAVA leetcode

整数除法

题目
给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 ‘*’、除号 ‘/’ 以及求余符号 ‘%’ 。

注意:
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2 31, 2 31−1]。本题中,如果除法结果溢出,则返回 2 31 − 1
代码

class Solution {
    public int divide(int a, int b) {
        int c=1;//判断商的正负
        if(a<-2147483647&&b==-1)//这种情况下商会溢出,溢出情况返回2147483647
        return 2147483647;
         if(a>0){
            a=-a;
            c=-c;
        }
        if(b>0){
            b=-b;
            c=-c;
        }
        int i =  divideCore(a,b);
        return c==1? i:-i;
}
private int divideCore(int a,int b){
   int middle = b;
   int result = 0;
   int midresult = 1;
   while(a <= b){
     middle = b;//其值为b*2^k
     midresult = 1;//其值为2^k
     while( middle >= 0xc0000000 && a <= middle+middle){
     middle += middle;
     midresult += midresult;
     }
    result += midresult;
     a -= middle;
   }
   return result;
}
}

注意:
1. int的取值范围为[-231 ~231-1 ],所以如果把负数转化为正数然后求商,会出现溢出问题(如果被除数a为-231转化为正数,然后去求商,会产生溢出),所有把正数转化为负数然后求商,就不会溢出
2. 被除数a依次减去除数b,其时间复杂度为O(n)
被除数a依次减去可以减去的最大b*2k ,其时间复杂度为O(log n )
3. 为什么要添加 middle >= 0xc0000000?
我看了其它人的解释是“为了防止int型dividend溢出,所以value值最多是-2的31次方的一半,所以得大于0xc0000000”,我个人理解的是 a <= middle+middle中,它会先将middle与middle进行相加,然后保存为int类型变量,然后与a进行判断,如果middle的值大于230 ,其相加以后的值保存为int类型变量会产生溢出,然后它会将其值变为231 -1,如果这时被除数a的值为231 -1,本该结束while循环,这时却又继续了,如下图的示例。所有需要添加 middle >= 0xc0000000。
整数除法 JAVA leetcode_第1张图片

你可能感兴趣的:(js,算法练习,leetcode,java,算法)